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