1 //===- X86Operand.h - Parsed X86 machine instruction ------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H 11 #define LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H 12 13 #include "InstPrinter/X86IntelInstPrinter.h" 14 #include "MCTargetDesc/X86MCTargetDesc.h" 15 #include "X86AsmParserCommon.h" 16 #include "llvm/ADT/STLExtras.h" 17 #include "llvm/ADT/StringRef.h" 18 #include "llvm/MC/MCExpr.h" 19 #include "llvm/MC/MCInst.h" 20 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 21 #include "llvm/MC/MCRegisterInfo.h" 22 #include "llvm/Support/Casting.h" 23 #include "llvm/Support/ErrorHandling.h" 24 #include "llvm/Support/SMLoc.h" 25 #include <cassert> 26 #include <memory> 27 28 namespace llvm { 29 30 /// X86Operand - Instances of this class represent a parsed X86 machine 31 /// instruction. 32 struct X86Operand final : public MCParsedAsmOperand { 33 enum KindTy { Token, Register, Immediate, Memory, Prefix, DXRegister } Kind; 34 35 SMLoc StartLoc, EndLoc; 36 SMLoc OffsetOfLoc; 37 StringRef SymName; 38 void *OpDecl; 39 bool AddressOf; 40 41 struct TokOp { 42 const char *Data; 43 unsigned Length; 44 }; 45 46 struct RegOp { 47 unsigned RegNo; 48 }; 49 50 struct PrefOp { 51 unsigned Prefixes; 52 }; 53 54 struct ImmOp { 55 const MCExpr *Val; 56 }; 57 58 struct MemOp { 59 unsigned SegReg; 60 const MCExpr *Disp; 61 unsigned BaseReg; 62 unsigned IndexReg; 63 unsigned Scale; 64 unsigned Size; 65 unsigned ModeSize; 66 67 /// If the memory operand is unsized and there are multiple instruction 68 /// matches, prefer the one with this size. 69 unsigned FrontendSize; 70 }; 71 72 union { 73 struct TokOp Tok; 74 struct RegOp Reg; 75 struct ImmOp Imm; 76 struct MemOp Mem; 77 struct PrefOp Pref; 78 }; 79 X86Operandfinal80 X86Operand(KindTy K, SMLoc Start, SMLoc End) 81 : Kind(K), StartLoc(Start), EndLoc(End) {} 82 getSymNamefinal83 StringRef getSymName() override { return SymName; } getOpDeclfinal84 void *getOpDecl() override { return OpDecl; } 85 86 /// getStartLoc - Get the location of the first token of this operand. getStartLocfinal87 SMLoc getStartLoc() const override { return StartLoc; } 88 89 /// getEndLoc - Get the location of the last token of this operand. getEndLocfinal90 SMLoc getEndLoc() const override { return EndLoc; } 91 92 /// getLocRange - Get the range between the first and last token of this 93 /// operand. getLocRangefinal94 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); } 95 96 /// getOffsetOfLoc - Get the location of the offset operator. getOffsetOfLocfinal97 SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; } 98 printfinal99 void print(raw_ostream &OS) const override { 100 101 auto PrintImmValue = [&](const MCExpr *Val, const char *VName) { 102 if (Val->getKind() == MCExpr::Constant) { 103 if (auto Imm = cast<MCConstantExpr>(Val)->getValue()) 104 OS << VName << Imm; 105 } else if (Val->getKind() == MCExpr::SymbolRef) { 106 if (auto *SRE = dyn_cast<MCSymbolRefExpr>(Val)) { 107 const MCSymbol &Sym = SRE->getSymbol(); 108 if (auto SymName = Sym.getName().data()) 109 OS << VName << SymName; 110 } 111 } 112 }; 113 114 switch (Kind) { 115 case Token: 116 OS << Tok.Data; 117 break; 118 case Register: 119 OS << "Reg:" << X86IntelInstPrinter::getRegisterName(Reg.RegNo); 120 break; 121 case DXRegister: 122 OS << "DXReg"; 123 break; 124 case Immediate: 125 PrintImmValue(Imm.Val, "Imm:"); 126 break; 127 case Prefix: 128 OS << "Prefix:" << Pref.Prefixes; 129 break; 130 case Memory: 131 OS << "Memory: ModeSize=" << Mem.ModeSize; 132 if (Mem.Size) 133 OS << ",Size=" << Mem.Size; 134 if (Mem.BaseReg) 135 OS << ",BaseReg=" << X86IntelInstPrinter::getRegisterName(Mem.BaseReg); 136 if (Mem.IndexReg) 137 OS << ",IndexReg=" 138 << X86IntelInstPrinter::getRegisterName(Mem.IndexReg); 139 if (Mem.Scale) 140 OS << ",Scale=" << Mem.Scale; 141 if (Mem.Disp) 142 PrintImmValue(Mem.Disp, ",Disp="); 143 if (Mem.SegReg) 144 OS << ",SegReg=" << X86IntelInstPrinter::getRegisterName(Mem.SegReg); 145 break; 146 } 147 } 148 getTokenfinal149 StringRef getToken() const { 150 assert(Kind == Token && "Invalid access!"); 151 return StringRef(Tok.Data, Tok.Length); 152 } setTokenValuefinal153 void setTokenValue(StringRef Value) { 154 assert(Kind == Token && "Invalid access!"); 155 Tok.Data = Value.data(); 156 Tok.Length = Value.size(); 157 } 158 getRegfinal159 unsigned getReg() const override { 160 assert(Kind == Register && "Invalid access!"); 161 return Reg.RegNo; 162 } 163 getPrefixfinal164 unsigned getPrefix() const { 165 assert(Kind == Prefix && "Invalid access!"); 166 return Pref.Prefixes; 167 } 168 getImmfinal169 const MCExpr *getImm() const { 170 assert(Kind == Immediate && "Invalid access!"); 171 return Imm.Val; 172 } 173 getMemDispfinal174 const MCExpr *getMemDisp() const { 175 assert(Kind == Memory && "Invalid access!"); 176 return Mem.Disp; 177 } getMemSegRegfinal178 unsigned getMemSegReg() const { 179 assert(Kind == Memory && "Invalid access!"); 180 return Mem.SegReg; 181 } getMemBaseRegfinal182 unsigned getMemBaseReg() const { 183 assert(Kind == Memory && "Invalid access!"); 184 return Mem.BaseReg; 185 } getMemIndexRegfinal186 unsigned getMemIndexReg() const { 187 assert(Kind == Memory && "Invalid access!"); 188 return Mem.IndexReg; 189 } getMemScalefinal190 unsigned getMemScale() const { 191 assert(Kind == Memory && "Invalid access!"); 192 return Mem.Scale; 193 } getMemModeSizefinal194 unsigned getMemModeSize() const { 195 assert(Kind == Memory && "Invalid access!"); 196 return Mem.ModeSize; 197 } getMemFrontendSizefinal198 unsigned getMemFrontendSize() const { 199 assert(Kind == Memory && "Invalid access!"); 200 return Mem.FrontendSize; 201 } 202 isTokenfinal203 bool isToken() const override {return Kind == Token; } 204 isImmfinal205 bool isImm() const override { return Kind == Immediate; } 206 isImmSExti16i8final207 bool isImmSExti16i8() const { 208 if (!isImm()) 209 return false; 210 211 // If this isn't a constant expr, just assume it fits and let relaxation 212 // handle it. 213 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 214 if (!CE) 215 return true; 216 217 // Otherwise, check the value is in a range that makes sense for this 218 // extension. 219 return isImmSExti16i8Value(CE->getValue()); 220 } isImmSExti32i8final221 bool isImmSExti32i8() const { 222 if (!isImm()) 223 return false; 224 225 // If this isn't a constant expr, just assume it fits and let relaxation 226 // handle it. 227 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 228 if (!CE) 229 return true; 230 231 // Otherwise, check the value is in a range that makes sense for this 232 // extension. 233 return isImmSExti32i8Value(CE->getValue()); 234 } isImmSExti64i8final235 bool isImmSExti64i8() const { 236 if (!isImm()) 237 return false; 238 239 // If this isn't a constant expr, just assume it fits and let relaxation 240 // handle it. 241 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 242 if (!CE) 243 return true; 244 245 // Otherwise, check the value is in a range that makes sense for this 246 // extension. 247 return isImmSExti64i8Value(CE->getValue()); 248 } isImmSExti64i32final249 bool isImmSExti64i32() const { 250 if (!isImm()) 251 return false; 252 253 // If this isn't a constant expr, just assume it fits and let relaxation 254 // handle it. 255 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 256 if (!CE) 257 return true; 258 259 // Otherwise, check the value is in a range that makes sense for this 260 // extension. 261 return isImmSExti64i32Value(CE->getValue()); 262 } 263 isImmUnsignedi8final264 bool isImmUnsignedi8() const { 265 if (!isImm()) return false; 266 // If this isn't a constant expr, just assume it fits and let relaxation 267 // handle it. 268 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 269 if (!CE) return true; 270 return isImmUnsignedi8Value(CE->getValue()); 271 } 272 isOffsetOffinal273 bool isOffsetOf() const override { 274 return OffsetOfLoc.getPointer(); 275 } 276 needAddressOffinal277 bool needAddressOf() const override { 278 return AddressOf; 279 } 280 isMemfinal281 bool isMem() const override { return Kind == Memory; } isMemUnsizedfinal282 bool isMemUnsized() const { 283 return Kind == Memory && Mem.Size == 0; 284 } isMem8final285 bool isMem8() const { 286 return Kind == Memory && (!Mem.Size || Mem.Size == 8); 287 } isMem16final288 bool isMem16() const { 289 return Kind == Memory && (!Mem.Size || Mem.Size == 16); 290 } isMem32final291 bool isMem32() const { 292 return Kind == Memory && (!Mem.Size || Mem.Size == 32); 293 } isMem64final294 bool isMem64() const { 295 return Kind == Memory && (!Mem.Size || Mem.Size == 64); 296 } isMem80final297 bool isMem80() const { 298 return Kind == Memory && (!Mem.Size || Mem.Size == 80); 299 } isMem128final300 bool isMem128() const { 301 return Kind == Memory && (!Mem.Size || Mem.Size == 128); 302 } isMem256final303 bool isMem256() const { 304 return Kind == Memory && (!Mem.Size || Mem.Size == 256); 305 } isMem512final306 bool isMem512() const { 307 return Kind == Memory && (!Mem.Size || Mem.Size == 512); 308 } isMemIndexRegfinal309 bool isMemIndexReg(unsigned LowR, unsigned HighR) const { 310 assert(Kind == Memory && "Invalid access!"); 311 return Mem.IndexReg >= LowR && Mem.IndexReg <= HighR; 312 } 313 isMem64_RC128final314 bool isMem64_RC128() const { 315 return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM15); 316 } isMem128_RC128final317 bool isMem128_RC128() const { 318 return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM15); 319 } isMem128_RC256final320 bool isMem128_RC256() const { 321 return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM15); 322 } isMem256_RC128final323 bool isMem256_RC128() const { 324 return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM15); 325 } isMem256_RC256final326 bool isMem256_RC256() const { 327 return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM15); 328 } 329 isMem64_RC128Xfinal330 bool isMem64_RC128X() const { 331 return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM31); 332 } isMem128_RC128Xfinal333 bool isMem128_RC128X() const { 334 return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM31); 335 } isMem128_RC256Xfinal336 bool isMem128_RC256X() const { 337 return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM31); 338 } isMem256_RC128Xfinal339 bool isMem256_RC128X() const { 340 return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM31); 341 } isMem256_RC256Xfinal342 bool isMem256_RC256X() const { 343 return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM31); 344 } isMem256_RC512final345 bool isMem256_RC512() const { 346 return isMem256() && isMemIndexReg(X86::ZMM0, X86::ZMM31); 347 } isMem512_RC256Xfinal348 bool isMem512_RC256X() const { 349 return isMem512() && isMemIndexReg(X86::YMM0, X86::YMM31); 350 } isMem512_RC512final351 bool isMem512_RC512() const { 352 return isMem512() && isMemIndexReg(X86::ZMM0, X86::ZMM31); 353 } 354 isAbsMemfinal355 bool isAbsMem() const { 356 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() && 357 !getMemIndexReg() && getMemScale() == 1; 358 } isAVX512RCfinal359 bool isAVX512RC() const{ 360 return isImm(); 361 } 362 isAbsMem16final363 bool isAbsMem16() const { 364 return isAbsMem() && Mem.ModeSize == 16; 365 } 366 isSrcIdxfinal367 bool isSrcIdx() const { 368 return !getMemIndexReg() && getMemScale() == 1 && 369 (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI || 370 getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) && 371 cast<MCConstantExpr>(getMemDisp())->getValue() == 0; 372 } isSrcIdx8final373 bool isSrcIdx8() const { 374 return isMem8() && isSrcIdx(); 375 } isSrcIdx16final376 bool isSrcIdx16() const { 377 return isMem16() && isSrcIdx(); 378 } isSrcIdx32final379 bool isSrcIdx32() const { 380 return isMem32() && isSrcIdx(); 381 } isSrcIdx64final382 bool isSrcIdx64() const { 383 return isMem64() && isSrcIdx(); 384 } 385 isDstIdxfinal386 bool isDstIdx() const { 387 return !getMemIndexReg() && getMemScale() == 1 && 388 (getMemSegReg() == 0 || getMemSegReg() == X86::ES) && 389 (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI || 390 getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) && 391 cast<MCConstantExpr>(getMemDisp())->getValue() == 0; 392 } isDstIdx8final393 bool isDstIdx8() const { 394 return isMem8() && isDstIdx(); 395 } isDstIdx16final396 bool isDstIdx16() const { 397 return isMem16() && isDstIdx(); 398 } isDstIdx32final399 bool isDstIdx32() const { 400 return isMem32() && isDstIdx(); 401 } isDstIdx64final402 bool isDstIdx64() const { 403 return isMem64() && isDstIdx(); 404 } 405 isMemOffsfinal406 bool isMemOffs() const { 407 return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() && 408 getMemScale() == 1; 409 } 410 isMemOffs16_8final411 bool isMemOffs16_8() const { 412 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8); 413 } isMemOffs16_16final414 bool isMemOffs16_16() const { 415 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16); 416 } isMemOffs16_32final417 bool isMemOffs16_32() const { 418 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32); 419 } isMemOffs32_8final420 bool isMemOffs32_8() const { 421 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8); 422 } isMemOffs32_16final423 bool isMemOffs32_16() const { 424 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16); 425 } isMemOffs32_32final426 bool isMemOffs32_32() const { 427 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32); 428 } isMemOffs32_64final429 bool isMemOffs32_64() const { 430 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64); 431 } isMemOffs64_8final432 bool isMemOffs64_8() const { 433 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8); 434 } isMemOffs64_16final435 bool isMemOffs64_16() const { 436 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16); 437 } isMemOffs64_32final438 bool isMemOffs64_32() const { 439 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32); 440 } isMemOffs64_64final441 bool isMemOffs64_64() const { 442 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64); 443 } 444 isPrefixfinal445 bool isPrefix() const { return Kind == Prefix; } isRegfinal446 bool isReg() const override { return Kind == Register; } isDXRegfinal447 bool isDXReg() const { return Kind == DXRegister; } 448 isGR32orGR64final449 bool isGR32orGR64() const { 450 return Kind == Register && 451 (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) || 452 X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg())); 453 } 454 addExprfinal455 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 456 // Add as immediates when possible. 457 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 458 Inst.addOperand(MCOperand::createImm(CE->getValue())); 459 else 460 Inst.addOperand(MCOperand::createExpr(Expr)); 461 } 462 addRegOperandsfinal463 void addRegOperands(MCInst &Inst, unsigned N) const { 464 assert(N == 1 && "Invalid number of operands!"); 465 Inst.addOperand(MCOperand::createReg(getReg())); 466 } 467 addGR32orGR64Operandsfinal468 void addGR32orGR64Operands(MCInst &Inst, unsigned N) const { 469 assert(N == 1 && "Invalid number of operands!"); 470 unsigned RegNo = getReg(); 471 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo)) 472 RegNo = getX86SubSuperRegister(RegNo, 32); 473 Inst.addOperand(MCOperand::createReg(RegNo)); 474 } 475 addAVX512RCOperandsfinal476 void addAVX512RCOperands(MCInst &Inst, unsigned N) const { 477 assert(N == 1 && "Invalid number of operands!"); 478 addExpr(Inst, getImm()); 479 } 480 addImmOperandsfinal481 void addImmOperands(MCInst &Inst, unsigned N) const { 482 assert(N == 1 && "Invalid number of operands!"); 483 addExpr(Inst, getImm()); 484 } 485 addMemOperandsfinal486 void addMemOperands(MCInst &Inst, unsigned N) const { 487 assert((N == 5) && "Invalid number of operands!"); 488 Inst.addOperand(MCOperand::createReg(getMemBaseReg())); 489 Inst.addOperand(MCOperand::createImm(getMemScale())); 490 Inst.addOperand(MCOperand::createReg(getMemIndexReg())); 491 addExpr(Inst, getMemDisp()); 492 Inst.addOperand(MCOperand::createReg(getMemSegReg())); 493 } 494 addAbsMemOperandsfinal495 void addAbsMemOperands(MCInst &Inst, unsigned N) const { 496 assert((N == 1) && "Invalid number of operands!"); 497 // Add as immediates when possible. 498 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp())) 499 Inst.addOperand(MCOperand::createImm(CE->getValue())); 500 else 501 Inst.addOperand(MCOperand::createExpr(getMemDisp())); 502 } 503 addSrcIdxOperandsfinal504 void addSrcIdxOperands(MCInst &Inst, unsigned N) const { 505 assert((N == 2) && "Invalid number of operands!"); 506 Inst.addOperand(MCOperand::createReg(getMemBaseReg())); 507 Inst.addOperand(MCOperand::createReg(getMemSegReg())); 508 } 509 addDstIdxOperandsfinal510 void addDstIdxOperands(MCInst &Inst, unsigned N) const { 511 assert((N == 1) && "Invalid number of operands!"); 512 Inst.addOperand(MCOperand::createReg(getMemBaseReg())); 513 } 514 addMemOffsOperandsfinal515 void addMemOffsOperands(MCInst &Inst, unsigned N) const { 516 assert((N == 2) && "Invalid number of operands!"); 517 // Add as immediates when possible. 518 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp())) 519 Inst.addOperand(MCOperand::createImm(CE->getValue())); 520 else 521 Inst.addOperand(MCOperand::createExpr(getMemDisp())); 522 Inst.addOperand(MCOperand::createReg(getMemSegReg())); 523 } 524 CreateTokenfinal525 static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) { 526 SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size()); 527 auto Res = llvm::make_unique<X86Operand>(Token, Loc, EndLoc); 528 Res->Tok.Data = Str.data(); 529 Res->Tok.Length = Str.size(); 530 return Res; 531 } 532 533 static std::unique_ptr<X86Operand> 534 CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc, 535 bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(), 536 StringRef SymName = StringRef(), void *OpDecl = nullptr) { 537 auto Res = llvm::make_unique<X86Operand>(Register, StartLoc, EndLoc); 538 Res->Reg.RegNo = RegNo; 539 Res->AddressOf = AddressOf; 540 Res->OffsetOfLoc = OffsetOfLoc; 541 Res->SymName = SymName; 542 Res->OpDecl = OpDecl; 543 return Res; 544 } 545 546 static std::unique_ptr<X86Operand> CreateDXRegfinal547 CreateDXReg(SMLoc StartLoc, SMLoc EndLoc) { 548 return llvm::make_unique<X86Operand>(DXRegister, StartLoc, EndLoc); 549 } 550 551 static std::unique_ptr<X86Operand> CreatePrefixfinal552 CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc) { 553 auto Res = llvm::make_unique<X86Operand>(Prefix, StartLoc, EndLoc); 554 Res->Pref.Prefixes = Prefixes; 555 return Res; 556 } 557 CreateImmfinal558 static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val, 559 SMLoc StartLoc, SMLoc EndLoc) { 560 auto Res = llvm::make_unique<X86Operand>(Immediate, StartLoc, EndLoc); 561 Res->Imm.Val = Val; 562 return Res; 563 } 564 565 /// Create an absolute memory operand. 566 static std::unique_ptr<X86Operand> 567 CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc, 568 unsigned Size = 0, StringRef SymName = StringRef(), 569 void *OpDecl = nullptr, unsigned FrontendSize = 0) { 570 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc); 571 Res->Mem.SegReg = 0; 572 Res->Mem.Disp = Disp; 573 Res->Mem.BaseReg = 0; 574 Res->Mem.IndexReg = 0; 575 Res->Mem.Scale = 1; 576 Res->Mem.Size = Size; 577 Res->Mem.ModeSize = ModeSize; 578 Res->Mem.FrontendSize = FrontendSize; 579 Res->SymName = SymName; 580 Res->OpDecl = OpDecl; 581 Res->AddressOf = false; 582 return Res; 583 } 584 585 /// Create a generalized memory operand. 586 static std::unique_ptr<X86Operand> 587 CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp, 588 unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc, 589 SMLoc EndLoc, unsigned Size = 0, StringRef SymName = StringRef(), 590 void *OpDecl = nullptr, unsigned FrontendSize = 0) { 591 // We should never just have a displacement, that should be parsed as an 592 // absolute memory operand. 593 assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!"); 594 595 // The scale should always be one of {1,2,4,8}. 596 assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) && 597 "Invalid scale!"); 598 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc); 599 Res->Mem.SegReg = SegReg; 600 Res->Mem.Disp = Disp; 601 Res->Mem.BaseReg = BaseReg; 602 Res->Mem.IndexReg = IndexReg; 603 Res->Mem.Scale = Scale; 604 Res->Mem.Size = Size; 605 Res->Mem.ModeSize = ModeSize; 606 Res->Mem.FrontendSize = FrontendSize; 607 Res->SymName = SymName; 608 Res->OpDecl = OpDecl; 609 Res->AddressOf = false; 610 return Res; 611 } 612 }; 613 614 } // end namespace llvm 615 616 #endif // LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H 617