123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724 |
- //===- X86Operand.h - Parsed X86 machine instruction ------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
- #define LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
- #include "MCTargetDesc/X86IntelInstPrinter.h"
- #include "MCTargetDesc/X86MCTargetDesc.h"
- #include "X86AsmParserCommon.h"
- #include "llvm/ADT/STLExtras.h"
- #include "llvm/ADT/StringRef.h"
- #include "llvm/MC/MCExpr.h"
- #include "llvm/MC/MCInst.h"
- #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
- #include "llvm/Support/Casting.h"
- #include "llvm/Support/SMLoc.h"
- #include <cassert>
- #include <memory>
- namespace llvm {
- /// X86Operand - Instances of this class represent a parsed X86 machine
- /// instruction.
- struct X86Operand final : public MCParsedAsmOperand {
- enum KindTy { Token, Register, Immediate, Memory, Prefix, DXRegister } Kind;
- SMLoc StartLoc, EndLoc;
- SMLoc OffsetOfLoc;
- StringRef SymName;
- void *OpDecl;
- bool AddressOf;
- struct TokOp {
- const char *Data;
- unsigned Length;
- };
- struct RegOp {
- unsigned RegNo;
- };
- struct PrefOp {
- unsigned Prefixes;
- };
- struct ImmOp {
- const MCExpr *Val;
- bool LocalRef;
- };
- struct MemOp {
- unsigned SegReg;
- const MCExpr *Disp;
- unsigned BaseReg;
- unsigned DefaultBaseReg;
- unsigned IndexReg;
- unsigned Scale;
- unsigned Size;
- unsigned ModeSize;
- /// If the memory operand is unsized and there are multiple instruction
- /// matches, prefer the one with this size.
- unsigned FrontendSize;
- };
- union {
- struct TokOp Tok;
- struct RegOp Reg;
- struct ImmOp Imm;
- struct MemOp Mem;
- struct PrefOp Pref;
- };
- X86Operand(KindTy K, SMLoc Start, SMLoc End)
- : Kind(K), StartLoc(Start), EndLoc(End), OpDecl(nullptr),
- AddressOf(false) {}
- StringRef getSymName() override { return SymName; }
- void *getOpDecl() override { return OpDecl; }
- /// getStartLoc - Get the location of the first token of this operand.
- SMLoc getStartLoc() const override { return StartLoc; }
- /// getEndLoc - Get the location of the last token of this operand.
- SMLoc getEndLoc() const override { return EndLoc; }
- /// getLocRange - Get the range between the first and last token of this
- /// operand.
- SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
- /// getOffsetOfLoc - Get the location of the offset operator.
- SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }
- void print(raw_ostream &OS) const override {
- auto PrintImmValue = [&](const MCExpr *Val, const char *VName) {
- if (Val->getKind() == MCExpr::Constant) {
- if (auto Imm = cast<MCConstantExpr>(Val)->getValue())
- OS << VName << Imm;
- } else if (Val->getKind() == MCExpr::SymbolRef) {
- if (auto *SRE = dyn_cast<MCSymbolRefExpr>(Val)) {
- const MCSymbol &Sym = SRE->getSymbol();
- if (const char *SymNameStr = Sym.getName().data())
- OS << VName << SymNameStr;
- }
- }
- };
- switch (Kind) {
- case Token:
- OS << Tok.Data;
- break;
- case Register:
- OS << "Reg:" << X86IntelInstPrinter::getRegisterName(Reg.RegNo);
- break;
- case DXRegister:
- OS << "DXReg";
- break;
- case Immediate:
- PrintImmValue(Imm.Val, "Imm:");
- break;
- case Prefix:
- OS << "Prefix:" << Pref.Prefixes;
- break;
- case Memory:
- OS << "Memory: ModeSize=" << Mem.ModeSize;
- if (Mem.Size)
- OS << ",Size=" << Mem.Size;
- if (Mem.BaseReg)
- OS << ",BaseReg=" << X86IntelInstPrinter::getRegisterName(Mem.BaseReg);
- if (Mem.IndexReg)
- OS << ",IndexReg="
- << X86IntelInstPrinter::getRegisterName(Mem.IndexReg);
- if (Mem.Scale)
- OS << ",Scale=" << Mem.Scale;
- if (Mem.Disp)
- PrintImmValue(Mem.Disp, ",Disp=");
- if (Mem.SegReg)
- OS << ",SegReg=" << X86IntelInstPrinter::getRegisterName(Mem.SegReg);
- break;
- }
- }
- StringRef getToken() const {
- assert(Kind == Token && "Invalid access!");
- return StringRef(Tok.Data, Tok.Length);
- }
- void setTokenValue(StringRef Value) {
- assert(Kind == Token && "Invalid access!");
- Tok.Data = Value.data();
- Tok.Length = Value.size();
- }
- unsigned getReg() const override {
- assert(Kind == Register && "Invalid access!");
- return Reg.RegNo;
- }
- unsigned getPrefix() const {
- assert(Kind == Prefix && "Invalid access!");
- return Pref.Prefixes;
- }
- const MCExpr *getImm() const {
- assert(Kind == Immediate && "Invalid access!");
- return Imm.Val;
- }
- const MCExpr *getMemDisp() const {
- assert(Kind == Memory && "Invalid access!");
- return Mem.Disp;
- }
- unsigned getMemSegReg() const {
- assert(Kind == Memory && "Invalid access!");
- return Mem.SegReg;
- }
- unsigned getMemBaseReg() const {
- assert(Kind == Memory && "Invalid access!");
- return Mem.BaseReg;
- }
- unsigned getMemDefaultBaseReg() const {
- assert(Kind == Memory && "Invalid access!");
- return Mem.DefaultBaseReg;
- }
- unsigned getMemIndexReg() const {
- assert(Kind == Memory && "Invalid access!");
- return Mem.IndexReg;
- }
- unsigned getMemScale() const {
- assert(Kind == Memory && "Invalid access!");
- return Mem.Scale;
- }
- unsigned getMemModeSize() const {
- assert(Kind == Memory && "Invalid access!");
- return Mem.ModeSize;
- }
- unsigned getMemFrontendSize() const {
- assert(Kind == Memory && "Invalid access!");
- return Mem.FrontendSize;
- }
- bool isToken() const override {return Kind == Token; }
- bool isImm() const override { return Kind == Immediate; }
- bool isImmSExti16i8() const {
- if (!isImm())
- return false;
- // If this isn't a constant expr, just assume it fits and let relaxation
- // handle it.
- const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
- if (!CE)
- return true;
- // Otherwise, check the value is in a range that makes sense for this
- // extension.
- return isImmSExti16i8Value(CE->getValue());
- }
- bool isImmSExti32i8() const {
- if (!isImm())
- return false;
- // If this isn't a constant expr, just assume it fits and let relaxation
- // handle it.
- const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
- if (!CE)
- return true;
- // Otherwise, check the value is in a range that makes sense for this
- // extension.
- return isImmSExti32i8Value(CE->getValue());
- }
- bool isImmSExti64i8() const {
- if (!isImm())
- return false;
- // If this isn't a constant expr, just assume it fits and let relaxation
- // handle it.
- const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
- if (!CE)
- return true;
- // Otherwise, check the value is in a range that makes sense for this
- // extension.
- return isImmSExti64i8Value(CE->getValue());
- }
- bool isImmSExti64i32() const {
- if (!isImm())
- return false;
- // If this isn't a constant expr, just assume it fits and let relaxation
- // handle it.
- const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
- if (!CE)
- return true;
- // Otherwise, check the value is in a range that makes sense for this
- // extension.
- return isImmSExti64i32Value(CE->getValue());
- }
- bool isImmUnsignedi4() const {
- if (!isImm()) return false;
- // If this isn't a constant expr, reject it. The immediate byte is shared
- // with a register encoding. We can't have it affected by a relocation.
- const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
- if (!CE) return false;
- return isImmUnsignedi4Value(CE->getValue());
- }
- bool isImmUnsignedi8() const {
- if (!isImm()) return false;
- // If this isn't a constant expr, just assume it fits and let relaxation
- // handle it.
- const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
- if (!CE) return true;
- return isImmUnsignedi8Value(CE->getValue());
- }
- bool isOffsetOfLocal() const override { return isImm() && Imm.LocalRef; }
- bool isMemPlaceholder(const MCInstrDesc &Desc) const override {
- // Only MS InlineAsm uses global variables with registers rather than
- // rip/eip.
- return isMem() && !Mem.DefaultBaseReg && Mem.FrontendSize;
- }
- bool needAddressOf() const override { return AddressOf; }
- bool isMem() const override { return Kind == Memory; }
- bool isMemUnsized() const {
- return Kind == Memory && Mem.Size == 0;
- }
- bool isMem8() const {
- return Kind == Memory && (!Mem.Size || Mem.Size == 8);
- }
- bool isMem16() const {
- return Kind == Memory && (!Mem.Size || Mem.Size == 16);
- }
- bool isMem32() const {
- return Kind == Memory && (!Mem.Size || Mem.Size == 32);
- }
- bool isMem64() const {
- return Kind == Memory && (!Mem.Size || Mem.Size == 64);
- }
- bool isMem80() const {
- return Kind == Memory && (!Mem.Size || Mem.Size == 80);
- }
- bool isMem128() const {
- return Kind == Memory && (!Mem.Size || Mem.Size == 128);
- }
- bool isMem256() const {
- return Kind == Memory && (!Mem.Size || Mem.Size == 256);
- }
- bool isMem512() const {
- return Kind == Memory && (!Mem.Size || Mem.Size == 512);
- }
- bool isSibMem() const {
- return isMem() && Mem.BaseReg != X86::RIP && Mem.BaseReg != X86::EIP;
- }
- bool isMemIndexReg(unsigned LowR, unsigned HighR) const {
- assert(Kind == Memory && "Invalid access!");
- return Mem.IndexReg >= LowR && Mem.IndexReg <= HighR;
- }
- bool isMem64_RC128() const {
- return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM15);
- }
- bool isMem128_RC128() const {
- return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM15);
- }
- bool isMem128_RC256() const {
- return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM15);
- }
- bool isMem256_RC128() const {
- return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM15);
- }
- bool isMem256_RC256() const {
- return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM15);
- }
- bool isMem64_RC128X() const {
- return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM31);
- }
- bool isMem128_RC128X() const {
- return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM31);
- }
- bool isMem128_RC256X() const {
- return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM31);
- }
- bool isMem256_RC128X() const {
- return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM31);
- }
- bool isMem256_RC256X() const {
- return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM31);
- }
- bool isMem256_RC512() const {
- return isMem256() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
- }
- bool isMem512_RC256X() const {
- return isMem512() && isMemIndexReg(X86::YMM0, X86::YMM31);
- }
- bool isMem512_RC512() const {
- return isMem512() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
- }
- bool isAbsMem() const {
- return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
- !getMemIndexReg() && getMemScale() == 1;
- }
- bool isAVX512RC() const{
- return isImm();
- }
- bool isAbsMem16() const {
- return isAbsMem() && Mem.ModeSize == 16;
- }
- bool isSrcIdx() const {
- return !getMemIndexReg() && getMemScale() == 1 &&
- (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
- getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
- cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
- }
- bool isSrcIdx8() const {
- return isMem8() && isSrcIdx();
- }
- bool isSrcIdx16() const {
- return isMem16() && isSrcIdx();
- }
- bool isSrcIdx32() const {
- return isMem32() && isSrcIdx();
- }
- bool isSrcIdx64() const {
- return isMem64() && isSrcIdx();
- }
- bool isDstIdx() const {
- return !getMemIndexReg() && getMemScale() == 1 &&
- (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
- (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
- getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&
- cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
- }
- bool isDstIdx8() const {
- return isMem8() && isDstIdx();
- }
- bool isDstIdx16() const {
- return isMem16() && isDstIdx();
- }
- bool isDstIdx32() const {
- return isMem32() && isDstIdx();
- }
- bool isDstIdx64() const {
- return isMem64() && isDstIdx();
- }
- bool isMemOffs() const {
- return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() &&
- getMemScale() == 1;
- }
- bool isMemOffs16_8() const {
- return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8);
- }
- bool isMemOffs16_16() const {
- return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16);
- }
- bool isMemOffs16_32() const {
- return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32);
- }
- bool isMemOffs32_8() const {
- return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8);
- }
- bool isMemOffs32_16() const {
- return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16);
- }
- bool isMemOffs32_32() const {
- return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);
- }
- bool isMemOffs32_64() const {
- return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64);
- }
- bool isMemOffs64_8() const {
- return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);
- }
- bool isMemOffs64_16() const {
- return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16);
- }
- bool isMemOffs64_32() const {
- return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32);
- }
- bool isMemOffs64_64() const {
- return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);
- }
- bool isPrefix() const { return Kind == Prefix; }
- bool isReg() const override { return Kind == Register; }
- bool isDXReg() const { return Kind == DXRegister; }
- bool isGR32orGR64() const {
- return Kind == Register &&
- (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
- X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
- }
- bool isGR16orGR32orGR64() const {
- return Kind == Register &&
- (X86MCRegisterClasses[X86::GR16RegClassID].contains(getReg()) ||
- X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
- X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
- }
- bool isVectorReg() const {
- return Kind == Register &&
- (X86MCRegisterClasses[X86::VR64RegClassID].contains(getReg()) ||
- X86MCRegisterClasses[X86::VR128XRegClassID].contains(getReg()) ||
- X86MCRegisterClasses[X86::VR256XRegClassID].contains(getReg()) ||
- X86MCRegisterClasses[X86::VR512RegClassID].contains(getReg()));
- }
- bool isVK1Pair() const {
- return Kind == Register &&
- X86MCRegisterClasses[X86::VK1RegClassID].contains(getReg());
- }
- bool isVK2Pair() const {
- return Kind == Register &&
- X86MCRegisterClasses[X86::VK2RegClassID].contains(getReg());
- }
- bool isVK4Pair() const {
- return Kind == Register &&
- X86MCRegisterClasses[X86::VK4RegClassID].contains(getReg());
- }
- bool isVK8Pair() const {
- return Kind == Register &&
- X86MCRegisterClasses[X86::VK8RegClassID].contains(getReg());
- }
- bool isVK16Pair() const {
- return Kind == Register &&
- X86MCRegisterClasses[X86::VK16RegClassID].contains(getReg());
- }
- void addExpr(MCInst &Inst, const MCExpr *Expr) const {
- // Add as immediates when possible.
- if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
- Inst.addOperand(MCOperand::createImm(CE->getValue()));
- else
- Inst.addOperand(MCOperand::createExpr(Expr));
- }
- void addRegOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(getReg()));
- }
- void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- MCRegister RegNo = getReg();
- if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
- RegNo = getX86SubSuperRegister(RegNo, 32);
- Inst.addOperand(MCOperand::createReg(RegNo));
- }
- void addGR16orGR32orGR64Operands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- MCRegister RegNo = getReg();
- if (X86MCRegisterClasses[X86::GR32RegClassID].contains(RegNo) ||
- X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
- RegNo = getX86SubSuperRegister(RegNo, 16);
- Inst.addOperand(MCOperand::createReg(RegNo));
- }
- void addAVX512RCOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- addExpr(Inst, getImm());
- }
- void addImmOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- addExpr(Inst, getImm());
- }
- void addMaskPairOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- unsigned Reg = getReg();
- switch (Reg) {
- case X86::K0:
- case X86::K1:
- Reg = X86::K0_K1;
- break;
- case X86::K2:
- case X86::K3:
- Reg = X86::K2_K3;
- break;
- case X86::K4:
- case X86::K5:
- Reg = X86::K4_K5;
- break;
- case X86::K6:
- case X86::K7:
- Reg = X86::K6_K7;
- break;
- }
- Inst.addOperand(MCOperand::createReg(Reg));
- }
- void addMemOperands(MCInst &Inst, unsigned N) const {
- assert((N == 5) && "Invalid number of operands!");
- if (getMemBaseReg())
- Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
- else
- Inst.addOperand(MCOperand::createReg(getMemDefaultBaseReg()));
- Inst.addOperand(MCOperand::createImm(getMemScale()));
- Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
- addExpr(Inst, getMemDisp());
- Inst.addOperand(MCOperand::createReg(getMemSegReg()));
- }
- void addAbsMemOperands(MCInst &Inst, unsigned N) const {
- assert((N == 1) && "Invalid number of operands!");
- // Add as immediates when possible.
- if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
- Inst.addOperand(MCOperand::createImm(CE->getValue()));
- else
- Inst.addOperand(MCOperand::createExpr(getMemDisp()));
- }
- void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
- assert((N == 2) && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
- Inst.addOperand(MCOperand::createReg(getMemSegReg()));
- }
- void addDstIdxOperands(MCInst &Inst, unsigned N) const {
- assert((N == 1) && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
- }
- void addMemOffsOperands(MCInst &Inst, unsigned N) const {
- assert((N == 2) && "Invalid number of operands!");
- // Add as immediates when possible.
- if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
- Inst.addOperand(MCOperand::createImm(CE->getValue()));
- else
- Inst.addOperand(MCOperand::createExpr(getMemDisp()));
- Inst.addOperand(MCOperand::createReg(getMemSegReg()));
- }
- static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
- SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
- auto Res = std::make_unique<X86Operand>(Token, Loc, EndLoc);
- Res->Tok.Data = Str.data();
- Res->Tok.Length = Str.size();
- return Res;
- }
- static std::unique_ptr<X86Operand>
- CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
- bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
- StringRef SymName = StringRef(), void *OpDecl = nullptr) {
- auto Res = std::make_unique<X86Operand>(Register, StartLoc, EndLoc);
- Res->Reg.RegNo = RegNo;
- Res->AddressOf = AddressOf;
- Res->OffsetOfLoc = OffsetOfLoc;
- Res->SymName = SymName;
- Res->OpDecl = OpDecl;
- return Res;
- }
- static std::unique_ptr<X86Operand>
- CreateDXReg(SMLoc StartLoc, SMLoc EndLoc) {
- return std::make_unique<X86Operand>(DXRegister, StartLoc, EndLoc);
- }
- static std::unique_ptr<X86Operand>
- CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc) {
- auto Res = std::make_unique<X86Operand>(Prefix, StartLoc, EndLoc);
- Res->Pref.Prefixes = Prefixes;
- return Res;
- }
- static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
- SMLoc StartLoc, SMLoc EndLoc,
- StringRef SymName = StringRef(),
- void *OpDecl = nullptr,
- bool GlobalRef = true) {
- auto Res = std::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
- Res->Imm.Val = Val;
- Res->Imm.LocalRef = !GlobalRef;
- Res->SymName = SymName;
- Res->OpDecl = OpDecl;
- Res->AddressOf = true;
- return Res;
- }
- /// Create an absolute memory operand.
- static std::unique_ptr<X86Operand>
- CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
- unsigned Size = 0, StringRef SymName = StringRef(),
- void *OpDecl = nullptr, unsigned FrontendSize = 0) {
- auto Res = std::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
- Res->Mem.SegReg = 0;
- Res->Mem.Disp = Disp;
- Res->Mem.BaseReg = 0;
- Res->Mem.DefaultBaseReg = 0;
- Res->Mem.IndexReg = 0;
- Res->Mem.Scale = 1;
- Res->Mem.Size = Size;
- Res->Mem.ModeSize = ModeSize;
- Res->Mem.FrontendSize = FrontendSize;
- Res->SymName = SymName;
- Res->OpDecl = OpDecl;
- Res->AddressOf = false;
- return Res;
- }
- /// Create a generalized memory operand.
- static std::unique_ptr<X86Operand>
- CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp,
- unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc,
- SMLoc EndLoc, unsigned Size = 0,
- unsigned DefaultBaseReg = X86::NoRegister,
- StringRef SymName = StringRef(), void *OpDecl = nullptr,
- unsigned FrontendSize = 0) {
- // We should never just have a displacement, that should be parsed as an
- // absolute memory operand.
- assert((SegReg || BaseReg || IndexReg || DefaultBaseReg) &&
- "Invalid memory operand!");
- // The scale should always be one of {1,2,4,8}.
- assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
- "Invalid scale!");
- auto Res = std::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
- Res->Mem.SegReg = SegReg;
- Res->Mem.Disp = Disp;
- Res->Mem.BaseReg = BaseReg;
- Res->Mem.DefaultBaseReg = DefaultBaseReg;
- Res->Mem.IndexReg = IndexReg;
- Res->Mem.Scale = Scale;
- Res->Mem.Size = Size;
- Res->Mem.ModeSize = ModeSize;
- Res->Mem.FrontendSize = FrontendSize;
- Res->SymName = SymName;
- Res->OpDecl = OpDecl;
- Res->AddressOf = false;
- return Res;
- }
- };
- } // end namespace llvm
- #endif // LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
|