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