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/Support/Casting.h" 21 #include "llvm/Support/SMLoc.h" 22 #include <cassert> 23 #include <memory> 24 25 namespace llvm { 26 27 /// X86Operand - Instances of this class represent a parsed X86 machine 28 /// instruction. 29 struct X86Operand final : public MCParsedAsmOperand { 30 enum KindTy { Token, Register, Immediate, Memory, Prefix, DXRegister } Kind; 31 32 SMLoc StartLoc, EndLoc; 33 SMLoc OffsetOfLoc; 34 StringRef SymName; 35 void *OpDecl; 36 bool AddressOf; 37 bool CallOperand; 38 39 struct TokOp { 40 const char *Data; 41 unsigned Length; 42 }; 43 44 struct RegOp { 45 unsigned RegNo; 46 }; 47 48 struct PrefOp { 49 unsigned Prefixes; 50 }; 51 52 struct ImmOp { 53 const MCExpr *Val; 54 bool LocalRef; 55 }; 56 57 struct MemOp { 58 unsigned SegReg; 59 const MCExpr *Disp; 60 unsigned BaseReg; 61 unsigned DefaultBaseReg; 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), CallOperand(false) {} 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 (const char *SymNameStr = Sym.getName().data()) 109 OS << VName << SymNameStr; 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 } getMemDefaultBaseRegfinal186 unsigned getMemDefaultBaseReg() const { 187 assert(Kind == Memory && "Invalid access!"); 188 return Mem.DefaultBaseReg; 189 } getMemIndexRegfinal190 unsigned getMemIndexReg() const { 191 assert(Kind == Memory && "Invalid access!"); 192 return Mem.IndexReg; 193 } getMemScalefinal194 unsigned getMemScale() const { 195 assert(Kind == Memory && "Invalid access!"); 196 return Mem.Scale; 197 } getMemModeSizefinal198 unsigned getMemModeSize() const { 199 assert(Kind == Memory && "Invalid access!"); 200 return Mem.ModeSize; 201 } getMemFrontendSizefinal202 unsigned getMemFrontendSize() const { 203 assert(Kind == Memory && "Invalid access!"); 204 return Mem.FrontendSize; 205 } 206 isTokenfinal207 bool isToken() const override {return Kind == Token; } 208 isImmfinal209 bool isImm() const override { return Kind == Immediate; } 210 isImmSExti16i8final211 bool isImmSExti16i8() const { 212 if (!isImm()) 213 return false; 214 215 // If this isn't a constant expr, just assume it fits and let relaxation 216 // handle it. 217 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 218 if (!CE) 219 return true; 220 221 // Otherwise, check the value is in a range that makes sense for this 222 // extension. 223 return isImmSExti16i8Value(CE->getValue()); 224 } isImmSExti32i8final225 bool isImmSExti32i8() const { 226 if (!isImm()) 227 return false; 228 229 // If this isn't a constant expr, just assume it fits and let relaxation 230 // 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 this 236 // extension. 237 return isImmSExti32i8Value(CE->getValue()); 238 } isImmSExti64i8final239 bool isImmSExti64i8() const { 240 if (!isImm()) 241 return false; 242 243 // If this isn't a constant expr, just assume it fits and let relaxation 244 // 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 this 250 // extension. 251 return isImmSExti64i8Value(CE->getValue()); 252 } isImmSExti64i32final253 bool isImmSExti64i32() const { 254 if (!isImm()) 255 return false; 256 257 // If this isn't a constant expr, just assume it fits and let relaxation 258 // 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 this 264 // extension. 265 return isImmSExti64i32Value(CE->getValue()); 266 } 267 isImmUnsignedi4final268 bool isImmUnsignedi4() const { 269 if (!isImm()) return false; 270 // If this isn't a constant expr, reject it. The immediate byte is shared 271 // with a register encoding. We can't have it affected by a relocation. 272 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 273 if (!CE) return false; 274 return isImmUnsignedi4Value(CE->getValue()); 275 } 276 isImmUnsignedi8final277 bool isImmUnsignedi8() const { 278 if (!isImm()) return false; 279 // If this isn't a constant expr, just assume it fits and let relaxation 280 // handle it. 281 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 282 if (!CE) return true; 283 return isImmUnsignedi8Value(CE->getValue()); 284 } 285 isOffsetOfLocalfinal286 bool isOffsetOfLocal() const override { return isImm() && Imm.LocalRef; } 287 needAddressOffinal288 bool needAddressOf() const override { return AddressOf; } 289 isMemfinal290 bool isMem() const override { return Kind == Memory; } isMemUnsizedfinal291 bool isMemUnsized() const { 292 return Kind == Memory && Mem.Size == 0; 293 } isMem8final294 bool isMem8() const { 295 return Kind == Memory && (!Mem.Size || Mem.Size == 8); 296 } isMem16final297 bool isMem16() const { 298 return Kind == Memory && (!Mem.Size || Mem.Size == 16); 299 } isMem32final300 bool isMem32() const { 301 return Kind == Memory && (!Mem.Size || Mem.Size == 32); 302 } isMem64final303 bool isMem64() const { 304 return Kind == Memory && (!Mem.Size || Mem.Size == 64); 305 } isMem80final306 bool isMem80() const { 307 return Kind == Memory && (!Mem.Size || Mem.Size == 80); 308 } isMem128final309 bool isMem128() const { 310 return Kind == Memory && (!Mem.Size || Mem.Size == 128); 311 } isMem256final312 bool isMem256() const { 313 return Kind == Memory && (!Mem.Size || Mem.Size == 256); 314 } isMem512final315 bool isMem512() const { 316 return Kind == Memory && (!Mem.Size || Mem.Size == 512); 317 } 318 isSibMemfinal319 bool isSibMem() const { 320 return isMem() && Mem.BaseReg != X86::RIP && Mem.BaseReg != X86::EIP; 321 } 322 isMemIndexRegfinal323 bool isMemIndexReg(unsigned LowR, unsigned HighR) const { 324 assert(Kind == Memory && "Invalid access!"); 325 return Mem.IndexReg >= LowR && Mem.IndexReg <= HighR; 326 } 327 isMem64_RC128final328 bool isMem64_RC128() const { 329 return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM15); 330 } isMem128_RC128final331 bool isMem128_RC128() const { 332 return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM15); 333 } isMem128_RC256final334 bool isMem128_RC256() const { 335 return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM15); 336 } isMem256_RC128final337 bool isMem256_RC128() const { 338 return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM15); 339 } isMem256_RC256final340 bool isMem256_RC256() const { 341 return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM15); 342 } 343 isMem64_RC128Xfinal344 bool isMem64_RC128X() const { 345 return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM31); 346 } isMem128_RC128Xfinal347 bool isMem128_RC128X() const { 348 return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM31); 349 } isMem128_RC256Xfinal350 bool isMem128_RC256X() const { 351 return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM31); 352 } isMem256_RC128Xfinal353 bool isMem256_RC128X() const { 354 return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM31); 355 } isMem256_RC256Xfinal356 bool isMem256_RC256X() const { 357 return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM31); 358 } isMem256_RC512final359 bool isMem256_RC512() const { 360 return isMem256() && isMemIndexReg(X86::ZMM0, X86::ZMM31); 361 } isMem512_RC256Xfinal362 bool isMem512_RC256X() const { 363 return isMem512() && isMemIndexReg(X86::YMM0, X86::YMM31); 364 } isMem512_RC512final365 bool isMem512_RC512() const { 366 return isMem512() && isMemIndexReg(X86::ZMM0, X86::ZMM31); 367 } 368 isAbsMemfinal369 bool isAbsMem() const { 370 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() && 371 !getMemIndexReg() && getMemScale() == 1; 372 } isAVX512RCfinal373 bool isAVX512RC() const{ 374 return isImm(); 375 } 376 isAbsMem16final377 bool isAbsMem16() const { 378 return isAbsMem() && Mem.ModeSize == 16; 379 } 380 isSrcIdxfinal381 bool isSrcIdx() const { 382 return !getMemIndexReg() && getMemScale() == 1 && 383 (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI || 384 getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) && 385 cast<MCConstantExpr>(getMemDisp())->getValue() == 0; 386 } isSrcIdx8final387 bool isSrcIdx8() const { 388 return isMem8() && isSrcIdx(); 389 } isSrcIdx16final390 bool isSrcIdx16() const { 391 return isMem16() && isSrcIdx(); 392 } isSrcIdx32final393 bool isSrcIdx32() const { 394 return isMem32() && isSrcIdx(); 395 } isSrcIdx64final396 bool isSrcIdx64() const { 397 return isMem64() && isSrcIdx(); 398 } 399 isDstIdxfinal400 bool isDstIdx() const { 401 return !getMemIndexReg() && getMemScale() == 1 && 402 (getMemSegReg() == 0 || getMemSegReg() == X86::ES) && 403 (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI || 404 getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) && 405 cast<MCConstantExpr>(getMemDisp())->getValue() == 0; 406 } isDstIdx8final407 bool isDstIdx8() const { 408 return isMem8() && isDstIdx(); 409 } isDstIdx16final410 bool isDstIdx16() const { 411 return isMem16() && isDstIdx(); 412 } isDstIdx32final413 bool isDstIdx32() const { 414 return isMem32() && isDstIdx(); 415 } isDstIdx64final416 bool isDstIdx64() const { 417 return isMem64() && isDstIdx(); 418 } 419 isMemOffsfinal420 bool isMemOffs() const { 421 return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() && 422 getMemScale() == 1; 423 } 424 isMemOffs16_8final425 bool isMemOffs16_8() const { 426 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8); 427 } isMemOffs16_16final428 bool isMemOffs16_16() const { 429 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16); 430 } isMemOffs16_32final431 bool isMemOffs16_32() const { 432 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32); 433 } isMemOffs32_8final434 bool isMemOffs32_8() const { 435 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8); 436 } isMemOffs32_16final437 bool isMemOffs32_16() const { 438 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16); 439 } isMemOffs32_32final440 bool isMemOffs32_32() const { 441 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32); 442 } isMemOffs32_64final443 bool isMemOffs32_64() const { 444 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64); 445 } isMemOffs64_8final446 bool isMemOffs64_8() const { 447 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8); 448 } isMemOffs64_16final449 bool isMemOffs64_16() const { 450 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16); 451 } isMemOffs64_32final452 bool isMemOffs64_32() const { 453 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32); 454 } isMemOffs64_64final455 bool isMemOffs64_64() const { 456 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64); 457 } 458 isPrefixfinal459 bool isPrefix() const { return Kind == Prefix; } isRegfinal460 bool isReg() const override { return Kind == Register; } isDXRegfinal461 bool isDXReg() const { return Kind == DXRegister; } 462 isGR32orGR64final463 bool isGR32orGR64() const { 464 return Kind == Register && 465 (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) || 466 X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg())); 467 } 468 isVectorRegfinal469 bool isVectorReg() const { 470 return Kind == Register && 471 (X86MCRegisterClasses[X86::VR64RegClassID].contains(getReg()) || 472 X86MCRegisterClasses[X86::VR128XRegClassID].contains(getReg()) || 473 X86MCRegisterClasses[X86::VR256XRegClassID].contains(getReg()) || 474 X86MCRegisterClasses[X86::VR512RegClassID].contains(getReg())); 475 } 476 isVK1Pairfinal477 bool isVK1Pair() const { 478 return Kind == Register && 479 X86MCRegisterClasses[X86::VK1RegClassID].contains(getReg()); 480 } 481 isVK2Pairfinal482 bool isVK2Pair() const { 483 return Kind == Register && 484 X86MCRegisterClasses[X86::VK2RegClassID].contains(getReg()); 485 } 486 isVK4Pairfinal487 bool isVK4Pair() const { 488 return Kind == Register && 489 X86MCRegisterClasses[X86::VK4RegClassID].contains(getReg()); 490 } 491 isVK8Pairfinal492 bool isVK8Pair() const { 493 return Kind == Register && 494 X86MCRegisterClasses[X86::VK8RegClassID].contains(getReg()); 495 } 496 isVK16Pairfinal497 bool isVK16Pair() const { 498 return Kind == Register && 499 X86MCRegisterClasses[X86::VK16RegClassID].contains(getReg()); 500 } 501 addExprfinal502 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 503 // Add as immediates when possible. 504 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 505 Inst.addOperand(MCOperand::createImm(CE->getValue())); 506 else 507 Inst.addOperand(MCOperand::createExpr(Expr)); 508 } 509 addRegOperandsfinal510 void addRegOperands(MCInst &Inst, unsigned N) const { 511 assert(N == 1 && "Invalid number of operands!"); 512 Inst.addOperand(MCOperand::createReg(getReg())); 513 } 514 addGR32orGR64Operandsfinal515 void addGR32orGR64Operands(MCInst &Inst, unsigned N) const { 516 assert(N == 1 && "Invalid number of operands!"); 517 MCRegister RegNo = getReg(); 518 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo)) 519 RegNo = getX86SubSuperRegister(RegNo, 32); 520 Inst.addOperand(MCOperand::createReg(RegNo)); 521 } 522 addAVX512RCOperandsfinal523 void addAVX512RCOperands(MCInst &Inst, unsigned N) const { 524 assert(N == 1 && "Invalid number of operands!"); 525 addExpr(Inst, getImm()); 526 } 527 addImmOperandsfinal528 void addImmOperands(MCInst &Inst, unsigned N) const { 529 assert(N == 1 && "Invalid number of operands!"); 530 addExpr(Inst, getImm()); 531 } 532 addMaskPairOperandsfinal533 void addMaskPairOperands(MCInst &Inst, unsigned N) const { 534 assert(N == 1 && "Invalid number of operands!"); 535 unsigned Reg = getReg(); 536 switch (Reg) { 537 case X86::K0: 538 case X86::K1: 539 Reg = X86::K0_K1; 540 break; 541 case X86::K2: 542 case X86::K3: 543 Reg = X86::K2_K3; 544 break; 545 case X86::K4: 546 case X86::K5: 547 Reg = X86::K4_K5; 548 break; 549 case X86::K6: 550 case X86::K7: 551 Reg = X86::K6_K7; 552 break; 553 } 554 Inst.addOperand(MCOperand::createReg(Reg)); 555 } 556 addMemOperandsfinal557 void addMemOperands(MCInst &Inst, unsigned N) const { 558 assert((N == 5) && "Invalid number of operands!"); 559 if (getMemBaseReg()) 560 Inst.addOperand(MCOperand::createReg(getMemBaseReg())); 561 else 562 Inst.addOperand(MCOperand::createReg(getMemDefaultBaseReg())); 563 Inst.addOperand(MCOperand::createImm(getMemScale())); 564 Inst.addOperand(MCOperand::createReg(getMemIndexReg())); 565 addExpr(Inst, getMemDisp()); 566 Inst.addOperand(MCOperand::createReg(getMemSegReg())); 567 } 568 addAbsMemOperandsfinal569 void addAbsMemOperands(MCInst &Inst, unsigned N) const { 570 assert((N == 1) && "Invalid number of operands!"); 571 // Add as immediates when possible. 572 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp())) 573 Inst.addOperand(MCOperand::createImm(CE->getValue())); 574 else 575 Inst.addOperand(MCOperand::createExpr(getMemDisp())); 576 } 577 addSrcIdxOperandsfinal578 void addSrcIdxOperands(MCInst &Inst, unsigned N) const { 579 assert((N == 2) && "Invalid number of operands!"); 580 Inst.addOperand(MCOperand::createReg(getMemBaseReg())); 581 Inst.addOperand(MCOperand::createReg(getMemSegReg())); 582 } 583 addDstIdxOperandsfinal584 void addDstIdxOperands(MCInst &Inst, unsigned N) const { 585 assert((N == 1) && "Invalid number of operands!"); 586 Inst.addOperand(MCOperand::createReg(getMemBaseReg())); 587 } 588 addMemOffsOperandsfinal589 void addMemOffsOperands(MCInst &Inst, unsigned N) const { 590 assert((N == 2) && "Invalid number of operands!"); 591 // Add as immediates when possible. 592 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp())) 593 Inst.addOperand(MCOperand::createImm(CE->getValue())); 594 else 595 Inst.addOperand(MCOperand::createExpr(getMemDisp())); 596 Inst.addOperand(MCOperand::createReg(getMemSegReg())); 597 } 598 CreateTokenfinal599 static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) { 600 SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size()); 601 auto Res = std::make_unique<X86Operand>(Token, Loc, EndLoc); 602 Res->Tok.Data = Str.data(); 603 Res->Tok.Length = Str.size(); 604 return Res; 605 } 606 607 static std::unique_ptr<X86Operand> 608 CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc, 609 bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(), 610 StringRef SymName = StringRef(), void *OpDecl = nullptr) { 611 auto Res = std::make_unique<X86Operand>(Register, StartLoc, EndLoc); 612 Res->Reg.RegNo = RegNo; 613 Res->AddressOf = AddressOf; 614 Res->OffsetOfLoc = OffsetOfLoc; 615 Res->SymName = SymName; 616 Res->OpDecl = OpDecl; 617 return Res; 618 } 619 620 static std::unique_ptr<X86Operand> CreateDXRegfinal621 CreateDXReg(SMLoc StartLoc, SMLoc EndLoc) { 622 return std::make_unique<X86Operand>(DXRegister, StartLoc, EndLoc); 623 } 624 625 static std::unique_ptr<X86Operand> CreatePrefixfinal626 CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc) { 627 auto Res = std::make_unique<X86Operand>(Prefix, StartLoc, EndLoc); 628 Res->Pref.Prefixes = Prefixes; 629 return Res; 630 } 631 632 static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val, 633 SMLoc StartLoc, SMLoc EndLoc, 634 StringRef SymName = StringRef(), 635 void *OpDecl = nullptr, 636 bool GlobalRef = true) { 637 auto Res = std::make_unique<X86Operand>(Immediate, StartLoc, EndLoc); 638 Res->Imm.Val = Val; 639 Res->Imm.LocalRef = !GlobalRef; 640 Res->SymName = SymName; 641 Res->OpDecl = OpDecl; 642 Res->AddressOf = true; 643 return Res; 644 } 645 646 /// Create an absolute memory operand. 647 static std::unique_ptr<X86Operand> 648 CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc, 649 unsigned Size = 0, StringRef SymName = StringRef(), 650 void *OpDecl = nullptr, unsigned FrontendSize = 0) { 651 auto Res = std::make_unique<X86Operand>(Memory, StartLoc, EndLoc); 652 Res->Mem.SegReg = 0; 653 Res->Mem.Disp = Disp; 654 Res->Mem.BaseReg = 0; 655 Res->Mem.DefaultBaseReg = 0; 656 Res->Mem.IndexReg = 0; 657 Res->Mem.Scale = 1; 658 Res->Mem.Size = Size; 659 Res->Mem.ModeSize = ModeSize; 660 Res->Mem.FrontendSize = FrontendSize; 661 Res->SymName = SymName; 662 Res->OpDecl = OpDecl; 663 Res->AddressOf = false; 664 return Res; 665 } 666 667 /// Create a generalized memory operand. 668 static std::unique_ptr<X86Operand> 669 CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp, 670 unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc, 671 SMLoc EndLoc, unsigned Size = 0, 672 unsigned DefaultBaseReg = X86::NoRegister, 673 StringRef SymName = StringRef(), void *OpDecl = nullptr, 674 unsigned FrontendSize = 0) { 675 // We should never just have a displacement, that should be parsed as an 676 // absolute memory operand. 677 assert((SegReg || BaseReg || IndexReg || DefaultBaseReg) && 678 "Invalid memory operand!"); 679 680 // The scale should always be one of {1,2,4,8}. 681 assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) && 682 "Invalid scale!"); 683 auto Res = std::make_unique<X86Operand>(Memory, StartLoc, EndLoc); 684 Res->Mem.SegReg = SegReg; 685 Res->Mem.Disp = Disp; 686 Res->Mem.BaseReg = BaseReg; 687 Res->Mem.DefaultBaseReg = DefaultBaseReg; 688 Res->Mem.IndexReg = IndexReg; 689 Res->Mem.Scale = Scale; 690 Res->Mem.Size = Size; 691 Res->Mem.ModeSize = ModeSize; 692 Res->Mem.FrontendSize = FrontendSize; 693 Res->SymName = SymName; 694 Res->OpDecl = OpDecl; 695 Res->AddressOf = false; 696 return Res; 697 } 698 }; 699 700 } // end namespace llvm 701 702 #endif // LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H 703