1 //===-- X86AsmParser.cpp - Parse X86 assembly to MCInst instructions ------===// 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 #include "MCTargetDesc/X86BaseInfo.h" 10 #include "MCTargetDesc/X86IntelInstPrinter.h" 11 #include "MCTargetDesc/X86MCExpr.h" 12 #include "MCTargetDesc/X86TargetStreamer.h" 13 #include "TargetInfo/X86TargetInfo.h" 14 #include "X86AsmParserCommon.h" 15 #include "X86Operand.h" 16 #include "llvm/ADT/STLExtras.h" 17 #include "llvm/ADT/SmallString.h" 18 #include "llvm/ADT/SmallVector.h" 19 #include "llvm/ADT/StringSwitch.h" 20 #include "llvm/ADT/Twine.h" 21 #include "llvm/MC/MCContext.h" 22 #include "llvm/MC/MCExpr.h" 23 #include "llvm/MC/MCInst.h" 24 #include "llvm/MC/MCInstrInfo.h" 25 #include "llvm/MC/MCParser/MCAsmLexer.h" 26 #include "llvm/MC/MCParser/MCAsmParser.h" 27 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 28 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 29 #include "llvm/MC/MCRegisterInfo.h" 30 #include "llvm/MC/MCSection.h" 31 #include "llvm/MC/MCStreamer.h" 32 #include "llvm/MC/MCSubtargetInfo.h" 33 #include "llvm/MC/MCSymbol.h" 34 #include "llvm/MC/TargetRegistry.h" 35 #include "llvm/Support/CommandLine.h" 36 #include "llvm/Support/Compiler.h" 37 #include "llvm/Support/SourceMgr.h" 38 #include "llvm/Support/raw_ostream.h" 39 #include <algorithm> 40 #include <memory> 41 42 using namespace llvm; 43 44 static cl::opt<bool> LVIInlineAsmHardening( 45 "x86-experimental-lvi-inline-asm-hardening", 46 cl::desc("Harden inline assembly code that may be vulnerable to Load Value" 47 " Injection (LVI). This feature is experimental."), cl::Hidden); 48 49 static bool checkScale(unsigned Scale, StringRef &ErrMsg) { 50 if (Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) { 51 ErrMsg = "scale factor in address must be 1, 2, 4 or 8"; 52 return true; 53 } 54 return false; 55 } 56 57 namespace { 58 59 static const char OpPrecedence[] = { 60 0, // IC_OR 61 1, // IC_XOR 62 2, // IC_AND 63 4, // IC_LSHIFT 64 4, // IC_RSHIFT 65 5, // IC_PLUS 66 5, // IC_MINUS 67 6, // IC_MULTIPLY 68 6, // IC_DIVIDE 69 6, // IC_MOD 70 7, // IC_NOT 71 8, // IC_NEG 72 9, // IC_RPAREN 73 10, // IC_LPAREN 74 0, // IC_IMM 75 0, // IC_REGISTER 76 3, // IC_EQ 77 3, // IC_NE 78 3, // IC_LT 79 3, // IC_LE 80 3, // IC_GT 81 3 // IC_GE 82 }; 83 84 class X86AsmParser : public MCTargetAsmParser { 85 ParseInstructionInfo *InstInfo; 86 bool Code16GCC; 87 unsigned ForcedDataPrefix = 0; 88 89 enum VEXEncoding { 90 VEXEncoding_Default, 91 VEXEncoding_VEX, 92 VEXEncoding_VEX2, 93 VEXEncoding_VEX3, 94 VEXEncoding_EVEX, 95 }; 96 97 VEXEncoding ForcedVEXEncoding = VEXEncoding_Default; 98 99 enum DispEncoding { 100 DispEncoding_Default, 101 DispEncoding_Disp8, 102 DispEncoding_Disp32, 103 }; 104 105 DispEncoding ForcedDispEncoding = DispEncoding_Default; 106 107 private: 108 SMLoc consumeToken() { 109 MCAsmParser &Parser = getParser(); 110 SMLoc Result = Parser.getTok().getLoc(); 111 Parser.Lex(); 112 return Result; 113 } 114 115 X86TargetStreamer &getTargetStreamer() { 116 assert(getParser().getStreamer().getTargetStreamer() && 117 "do not have a target streamer"); 118 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); 119 return static_cast<X86TargetStreamer &>(TS); 120 } 121 122 unsigned MatchInstruction(const OperandVector &Operands, MCInst &Inst, 123 uint64_t &ErrorInfo, FeatureBitset &MissingFeatures, 124 bool matchingInlineAsm, unsigned VariantID = 0) { 125 // In Code16GCC mode, match as 32-bit. 126 if (Code16GCC) 127 SwitchMode(X86::Is32Bit); 128 unsigned rv = MatchInstructionImpl(Operands, Inst, ErrorInfo, 129 MissingFeatures, matchingInlineAsm, 130 VariantID); 131 if (Code16GCC) 132 SwitchMode(X86::Is16Bit); 133 return rv; 134 } 135 136 enum InfixCalculatorTok { 137 IC_OR = 0, 138 IC_XOR, 139 IC_AND, 140 IC_LSHIFT, 141 IC_RSHIFT, 142 IC_PLUS, 143 IC_MINUS, 144 IC_MULTIPLY, 145 IC_DIVIDE, 146 IC_MOD, 147 IC_NOT, 148 IC_NEG, 149 IC_RPAREN, 150 IC_LPAREN, 151 IC_IMM, 152 IC_REGISTER, 153 IC_EQ, 154 IC_NE, 155 IC_LT, 156 IC_LE, 157 IC_GT, 158 IC_GE 159 }; 160 161 enum IntelOperatorKind { 162 IOK_INVALID = 0, 163 IOK_LENGTH, 164 IOK_SIZE, 165 IOK_TYPE, 166 }; 167 168 enum MasmOperatorKind { 169 MOK_INVALID = 0, 170 MOK_LENGTHOF, 171 MOK_SIZEOF, 172 MOK_TYPE, 173 }; 174 175 class InfixCalculator { 176 typedef std::pair< InfixCalculatorTok, int64_t > ICToken; 177 SmallVector<InfixCalculatorTok, 4> InfixOperatorStack; 178 SmallVector<ICToken, 4> PostfixStack; 179 180 bool isUnaryOperator(InfixCalculatorTok Op) const { 181 return Op == IC_NEG || Op == IC_NOT; 182 } 183 184 public: 185 int64_t popOperand() { 186 assert (!PostfixStack.empty() && "Poped an empty stack!"); 187 ICToken Op = PostfixStack.pop_back_val(); 188 if (!(Op.first == IC_IMM || Op.first == IC_REGISTER)) 189 return -1; // The invalid Scale value will be caught later by checkScale 190 return Op.second; 191 } 192 void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) { 193 assert ((Op == IC_IMM || Op == IC_REGISTER) && 194 "Unexpected operand!"); 195 PostfixStack.push_back(std::make_pair(Op, Val)); 196 } 197 198 void popOperator() { InfixOperatorStack.pop_back(); } 199 void pushOperator(InfixCalculatorTok Op) { 200 // Push the new operator if the stack is empty. 201 if (InfixOperatorStack.empty()) { 202 InfixOperatorStack.push_back(Op); 203 return; 204 } 205 206 // Push the new operator if it has a higher precedence than the operator 207 // on the top of the stack or the operator on the top of the stack is a 208 // left parentheses. 209 unsigned Idx = InfixOperatorStack.size() - 1; 210 InfixCalculatorTok StackOp = InfixOperatorStack[Idx]; 211 if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) { 212 InfixOperatorStack.push_back(Op); 213 return; 214 } 215 216 // The operator on the top of the stack has higher precedence than the 217 // new operator. 218 unsigned ParenCount = 0; 219 while (true) { 220 // Nothing to process. 221 if (InfixOperatorStack.empty()) 222 break; 223 224 Idx = InfixOperatorStack.size() - 1; 225 StackOp = InfixOperatorStack[Idx]; 226 if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount)) 227 break; 228 229 // If we have an even parentheses count and we see a left parentheses, 230 // then stop processing. 231 if (!ParenCount && StackOp == IC_LPAREN) 232 break; 233 234 if (StackOp == IC_RPAREN) { 235 ++ParenCount; 236 InfixOperatorStack.pop_back(); 237 } else if (StackOp == IC_LPAREN) { 238 --ParenCount; 239 InfixOperatorStack.pop_back(); 240 } else { 241 InfixOperatorStack.pop_back(); 242 PostfixStack.push_back(std::make_pair(StackOp, 0)); 243 } 244 } 245 // Push the new operator. 246 InfixOperatorStack.push_back(Op); 247 } 248 249 int64_t execute() { 250 // Push any remaining operators onto the postfix stack. 251 while (!InfixOperatorStack.empty()) { 252 InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val(); 253 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN) 254 PostfixStack.push_back(std::make_pair(StackOp, 0)); 255 } 256 257 if (PostfixStack.empty()) 258 return 0; 259 260 SmallVector<ICToken, 16> OperandStack; 261 for (unsigned i = 0, e = PostfixStack.size(); i != e; ++i) { 262 ICToken Op = PostfixStack[i]; 263 if (Op.first == IC_IMM || Op.first == IC_REGISTER) { 264 OperandStack.push_back(Op); 265 } else if (isUnaryOperator(Op.first)) { 266 assert (OperandStack.size() > 0 && "Too few operands."); 267 ICToken Operand = OperandStack.pop_back_val(); 268 assert (Operand.first == IC_IMM && 269 "Unary operation with a register!"); 270 switch (Op.first) { 271 default: 272 report_fatal_error("Unexpected operator!"); 273 break; 274 case IC_NEG: 275 OperandStack.push_back(std::make_pair(IC_IMM, -Operand.second)); 276 break; 277 case IC_NOT: 278 OperandStack.push_back(std::make_pair(IC_IMM, ~Operand.second)); 279 break; 280 } 281 } else { 282 assert (OperandStack.size() > 1 && "Too few operands."); 283 int64_t Val; 284 ICToken Op2 = OperandStack.pop_back_val(); 285 ICToken Op1 = OperandStack.pop_back_val(); 286 switch (Op.first) { 287 default: 288 report_fatal_error("Unexpected operator!"); 289 break; 290 case IC_PLUS: 291 Val = Op1.second + Op2.second; 292 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 293 break; 294 case IC_MINUS: 295 Val = Op1.second - Op2.second; 296 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 297 break; 298 case IC_MULTIPLY: 299 assert (Op1.first == IC_IMM && Op2.first == IC_IMM && 300 "Multiply operation with an immediate and a register!"); 301 Val = Op1.second * Op2.second; 302 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 303 break; 304 case IC_DIVIDE: 305 assert (Op1.first == IC_IMM && Op2.first == IC_IMM && 306 "Divide operation with an immediate and a register!"); 307 assert (Op2.second != 0 && "Division by zero!"); 308 Val = Op1.second / Op2.second; 309 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 310 break; 311 case IC_MOD: 312 assert (Op1.first == IC_IMM && Op2.first == IC_IMM && 313 "Modulo operation with an immediate and a register!"); 314 Val = Op1.second % Op2.second; 315 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 316 break; 317 case IC_OR: 318 assert (Op1.first == IC_IMM && Op2.first == IC_IMM && 319 "Or operation with an immediate and a register!"); 320 Val = Op1.second | Op2.second; 321 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 322 break; 323 case IC_XOR: 324 assert(Op1.first == IC_IMM && Op2.first == IC_IMM && 325 "Xor operation with an immediate and a register!"); 326 Val = Op1.second ^ Op2.second; 327 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 328 break; 329 case IC_AND: 330 assert (Op1.first == IC_IMM && Op2.first == IC_IMM && 331 "And operation with an immediate and a register!"); 332 Val = Op1.second & Op2.second; 333 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 334 break; 335 case IC_LSHIFT: 336 assert (Op1.first == IC_IMM && Op2.first == IC_IMM && 337 "Left shift operation with an immediate and a register!"); 338 Val = Op1.second << Op2.second; 339 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 340 break; 341 case IC_RSHIFT: 342 assert (Op1.first == IC_IMM && Op2.first == IC_IMM && 343 "Right shift operation with an immediate and a register!"); 344 Val = Op1.second >> Op2.second; 345 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 346 break; 347 case IC_EQ: 348 assert(Op1.first == IC_IMM && Op2.first == IC_IMM && 349 "Equals operation with an immediate and a register!"); 350 Val = (Op1.second == Op2.second) ? -1 : 0; 351 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 352 break; 353 case IC_NE: 354 assert(Op1.first == IC_IMM && Op2.first == IC_IMM && 355 "Not-equals operation with an immediate and a register!"); 356 Val = (Op1.second != Op2.second) ? -1 : 0; 357 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 358 break; 359 case IC_LT: 360 assert(Op1.first == IC_IMM && Op2.first == IC_IMM && 361 "Less-than operation with an immediate and a register!"); 362 Val = (Op1.second < Op2.second) ? -1 : 0; 363 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 364 break; 365 case IC_LE: 366 assert(Op1.first == IC_IMM && Op2.first == IC_IMM && 367 "Less-than-or-equal operation with an immediate and a " 368 "register!"); 369 Val = (Op1.second <= Op2.second) ? -1 : 0; 370 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 371 break; 372 case IC_GT: 373 assert(Op1.first == IC_IMM && Op2.first == IC_IMM && 374 "Greater-than operation with an immediate and a register!"); 375 Val = (Op1.second > Op2.second) ? -1 : 0; 376 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 377 break; 378 case IC_GE: 379 assert(Op1.first == IC_IMM && Op2.first == IC_IMM && 380 "Greater-than-or-equal operation with an immediate and a " 381 "register!"); 382 Val = (Op1.second >= Op2.second) ? -1 : 0; 383 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 384 break; 385 } 386 } 387 } 388 assert (OperandStack.size() == 1 && "Expected a single result."); 389 return OperandStack.pop_back_val().second; 390 } 391 }; 392 393 enum IntelExprState { 394 IES_INIT, 395 IES_OR, 396 IES_XOR, 397 IES_AND, 398 IES_EQ, 399 IES_NE, 400 IES_LT, 401 IES_LE, 402 IES_GT, 403 IES_GE, 404 IES_LSHIFT, 405 IES_RSHIFT, 406 IES_PLUS, 407 IES_MINUS, 408 IES_OFFSET, 409 IES_CAST, 410 IES_NOT, 411 IES_MULTIPLY, 412 IES_DIVIDE, 413 IES_MOD, 414 IES_LBRAC, 415 IES_RBRAC, 416 IES_LPAREN, 417 IES_RPAREN, 418 IES_REGISTER, 419 IES_INTEGER, 420 IES_IDENTIFIER, 421 IES_ERROR 422 }; 423 424 class IntelExprStateMachine { 425 IntelExprState State = IES_INIT, PrevState = IES_ERROR; 426 unsigned BaseReg = 0, IndexReg = 0, TmpReg = 0, Scale = 0; 427 int64_t Imm = 0; 428 const MCExpr *Sym = nullptr; 429 StringRef SymName; 430 InfixCalculator IC; 431 InlineAsmIdentifierInfo Info; 432 short BracCount = 0; 433 bool MemExpr = false; 434 bool OffsetOperator = false; 435 bool AttachToOperandIdx = false; 436 bool IsPIC = false; 437 SMLoc OffsetOperatorLoc; 438 AsmTypeInfo CurType; 439 440 bool setSymRef(const MCExpr *Val, StringRef ID, StringRef &ErrMsg) { 441 if (Sym) { 442 ErrMsg = "cannot use more than one symbol in memory operand"; 443 return true; 444 } 445 Sym = Val; 446 SymName = ID; 447 return false; 448 } 449 450 public: 451 IntelExprStateMachine() = default; 452 453 void addImm(int64_t imm) { Imm += imm; } 454 short getBracCount() const { return BracCount; } 455 bool isMemExpr() const { return MemExpr; } 456 bool isOffsetOperator() const { return OffsetOperator; } 457 SMLoc getOffsetLoc() const { return OffsetOperatorLoc; } 458 unsigned getBaseReg() const { return BaseReg; } 459 unsigned getIndexReg() const { return IndexReg; } 460 unsigned getScale() const { return Scale; } 461 const MCExpr *getSym() const { return Sym; } 462 StringRef getSymName() const { return SymName; } 463 StringRef getType() const { return CurType.Name; } 464 unsigned getSize() const { return CurType.Size; } 465 unsigned getElementSize() const { return CurType.ElementSize; } 466 unsigned getLength() const { return CurType.Length; } 467 int64_t getImm() { return Imm + IC.execute(); } 468 bool isValidEndState() const { 469 return State == IES_RBRAC || State == IES_INTEGER; 470 } 471 472 // Is the intel expression appended after an operand index. 473 // [OperandIdx][Intel Expression] 474 // This is neccessary for checking if it is an independent 475 // intel expression at back end when parse inline asm. 476 void setAppendAfterOperand() { AttachToOperandIdx = true; } 477 478 bool isPIC() const { return IsPIC; } 479 void setPIC() { IsPIC = true; } 480 481 bool hadError() const { return State == IES_ERROR; } 482 const InlineAsmIdentifierInfo &getIdentifierInfo() const { return Info; } 483 484 bool regsUseUpError(StringRef &ErrMsg) { 485 // This case mostly happen in inline asm, e.g. Arr[BaseReg + IndexReg] 486 // can not intruduce additional register in inline asm in PIC model. 487 if (IsPIC && AttachToOperandIdx) 488 ErrMsg = "Don't use 2 or more regs for mem offset in PIC model!"; 489 else 490 ErrMsg = "BaseReg/IndexReg already set!"; 491 return true; 492 } 493 494 void onOr() { 495 IntelExprState CurrState = State; 496 switch (State) { 497 default: 498 State = IES_ERROR; 499 break; 500 case IES_INTEGER: 501 case IES_RPAREN: 502 case IES_REGISTER: 503 State = IES_OR; 504 IC.pushOperator(IC_OR); 505 break; 506 } 507 PrevState = CurrState; 508 } 509 void onXor() { 510 IntelExprState CurrState = State; 511 switch (State) { 512 default: 513 State = IES_ERROR; 514 break; 515 case IES_INTEGER: 516 case IES_RPAREN: 517 case IES_REGISTER: 518 State = IES_XOR; 519 IC.pushOperator(IC_XOR); 520 break; 521 } 522 PrevState = CurrState; 523 } 524 void onAnd() { 525 IntelExprState CurrState = State; 526 switch (State) { 527 default: 528 State = IES_ERROR; 529 break; 530 case IES_INTEGER: 531 case IES_RPAREN: 532 case IES_REGISTER: 533 State = IES_AND; 534 IC.pushOperator(IC_AND); 535 break; 536 } 537 PrevState = CurrState; 538 } 539 void onEq() { 540 IntelExprState CurrState = State; 541 switch (State) { 542 default: 543 State = IES_ERROR; 544 break; 545 case IES_INTEGER: 546 case IES_RPAREN: 547 case IES_REGISTER: 548 State = IES_EQ; 549 IC.pushOperator(IC_EQ); 550 break; 551 } 552 PrevState = CurrState; 553 } 554 void onNE() { 555 IntelExprState CurrState = State; 556 switch (State) { 557 default: 558 State = IES_ERROR; 559 break; 560 case IES_INTEGER: 561 case IES_RPAREN: 562 case IES_REGISTER: 563 State = IES_NE; 564 IC.pushOperator(IC_NE); 565 break; 566 } 567 PrevState = CurrState; 568 } 569 void onLT() { 570 IntelExprState CurrState = State; 571 switch (State) { 572 default: 573 State = IES_ERROR; 574 break; 575 case IES_INTEGER: 576 case IES_RPAREN: 577 case IES_REGISTER: 578 State = IES_LT; 579 IC.pushOperator(IC_LT); 580 break; 581 } 582 PrevState = CurrState; 583 } 584 void onLE() { 585 IntelExprState CurrState = State; 586 switch (State) { 587 default: 588 State = IES_ERROR; 589 break; 590 case IES_INTEGER: 591 case IES_RPAREN: 592 case IES_REGISTER: 593 State = IES_LE; 594 IC.pushOperator(IC_LE); 595 break; 596 } 597 PrevState = CurrState; 598 } 599 void onGT() { 600 IntelExprState CurrState = State; 601 switch (State) { 602 default: 603 State = IES_ERROR; 604 break; 605 case IES_INTEGER: 606 case IES_RPAREN: 607 case IES_REGISTER: 608 State = IES_GT; 609 IC.pushOperator(IC_GT); 610 break; 611 } 612 PrevState = CurrState; 613 } 614 void onGE() { 615 IntelExprState CurrState = State; 616 switch (State) { 617 default: 618 State = IES_ERROR; 619 break; 620 case IES_INTEGER: 621 case IES_RPAREN: 622 case IES_REGISTER: 623 State = IES_GE; 624 IC.pushOperator(IC_GE); 625 break; 626 } 627 PrevState = CurrState; 628 } 629 void onLShift() { 630 IntelExprState CurrState = State; 631 switch (State) { 632 default: 633 State = IES_ERROR; 634 break; 635 case IES_INTEGER: 636 case IES_RPAREN: 637 case IES_REGISTER: 638 State = IES_LSHIFT; 639 IC.pushOperator(IC_LSHIFT); 640 break; 641 } 642 PrevState = CurrState; 643 } 644 void onRShift() { 645 IntelExprState CurrState = State; 646 switch (State) { 647 default: 648 State = IES_ERROR; 649 break; 650 case IES_INTEGER: 651 case IES_RPAREN: 652 case IES_REGISTER: 653 State = IES_RSHIFT; 654 IC.pushOperator(IC_RSHIFT); 655 break; 656 } 657 PrevState = CurrState; 658 } 659 bool onPlus(StringRef &ErrMsg) { 660 IntelExprState CurrState = State; 661 switch (State) { 662 default: 663 State = IES_ERROR; 664 break; 665 case IES_INTEGER: 666 case IES_RPAREN: 667 case IES_REGISTER: 668 case IES_OFFSET: 669 State = IES_PLUS; 670 IC.pushOperator(IC_PLUS); 671 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) { 672 // If we already have a BaseReg, then assume this is the IndexReg with 673 // no explicit scale. 674 if (!BaseReg) { 675 BaseReg = TmpReg; 676 } else { 677 if (IndexReg) 678 return regsUseUpError(ErrMsg); 679 IndexReg = TmpReg; 680 Scale = 0; 681 } 682 } 683 break; 684 } 685 PrevState = CurrState; 686 return false; 687 } 688 bool onMinus(StringRef &ErrMsg) { 689 IntelExprState CurrState = State; 690 switch (State) { 691 default: 692 State = IES_ERROR; 693 break; 694 case IES_OR: 695 case IES_XOR: 696 case IES_AND: 697 case IES_EQ: 698 case IES_NE: 699 case IES_LT: 700 case IES_LE: 701 case IES_GT: 702 case IES_GE: 703 case IES_LSHIFT: 704 case IES_RSHIFT: 705 case IES_PLUS: 706 case IES_NOT: 707 case IES_MULTIPLY: 708 case IES_DIVIDE: 709 case IES_MOD: 710 case IES_LPAREN: 711 case IES_RPAREN: 712 case IES_LBRAC: 713 case IES_RBRAC: 714 case IES_INTEGER: 715 case IES_REGISTER: 716 case IES_INIT: 717 case IES_OFFSET: 718 State = IES_MINUS; 719 // push minus operator if it is not a negate operator 720 if (CurrState == IES_REGISTER || CurrState == IES_RPAREN || 721 CurrState == IES_INTEGER || CurrState == IES_RBRAC || 722 CurrState == IES_OFFSET) 723 IC.pushOperator(IC_MINUS); 724 else if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) { 725 // We have negate operator for Scale: it's illegal 726 ErrMsg = "Scale can't be negative"; 727 return true; 728 } else 729 IC.pushOperator(IC_NEG); 730 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) { 731 // If we already have a BaseReg, then assume this is the IndexReg with 732 // no explicit scale. 733 if (!BaseReg) { 734 BaseReg = TmpReg; 735 } else { 736 if (IndexReg) 737 return regsUseUpError(ErrMsg); 738 IndexReg = TmpReg; 739 Scale = 0; 740 } 741 } 742 break; 743 } 744 PrevState = CurrState; 745 return false; 746 } 747 void onNot() { 748 IntelExprState CurrState = State; 749 switch (State) { 750 default: 751 State = IES_ERROR; 752 break; 753 case IES_OR: 754 case IES_XOR: 755 case IES_AND: 756 case IES_EQ: 757 case IES_NE: 758 case IES_LT: 759 case IES_LE: 760 case IES_GT: 761 case IES_GE: 762 case IES_LSHIFT: 763 case IES_RSHIFT: 764 case IES_PLUS: 765 case IES_MINUS: 766 case IES_NOT: 767 case IES_MULTIPLY: 768 case IES_DIVIDE: 769 case IES_MOD: 770 case IES_LPAREN: 771 case IES_LBRAC: 772 case IES_INIT: 773 State = IES_NOT; 774 IC.pushOperator(IC_NOT); 775 break; 776 } 777 PrevState = CurrState; 778 } 779 bool onRegister(unsigned Reg, StringRef &ErrMsg) { 780 IntelExprState CurrState = State; 781 switch (State) { 782 default: 783 State = IES_ERROR; 784 break; 785 case IES_PLUS: 786 case IES_LPAREN: 787 case IES_LBRAC: 788 State = IES_REGISTER; 789 TmpReg = Reg; 790 IC.pushOperand(IC_REGISTER); 791 break; 792 case IES_MULTIPLY: 793 // Index Register - Scale * Register 794 if (PrevState == IES_INTEGER) { 795 if (IndexReg) 796 return regsUseUpError(ErrMsg); 797 State = IES_REGISTER; 798 IndexReg = Reg; 799 // Get the scale and replace the 'Scale * Register' with '0'. 800 Scale = IC.popOperand(); 801 if (checkScale(Scale, ErrMsg)) 802 return true; 803 IC.pushOperand(IC_IMM); 804 IC.popOperator(); 805 } else { 806 State = IES_ERROR; 807 } 808 break; 809 } 810 PrevState = CurrState; 811 return false; 812 } 813 bool onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName, 814 const InlineAsmIdentifierInfo &IDInfo, 815 const AsmTypeInfo &Type, bool ParsingMSInlineAsm, 816 StringRef &ErrMsg) { 817 // InlineAsm: Treat an enum value as an integer 818 if (ParsingMSInlineAsm) 819 if (IDInfo.isKind(InlineAsmIdentifierInfo::IK_EnumVal)) 820 return onInteger(IDInfo.Enum.EnumVal, ErrMsg); 821 // Treat a symbolic constant like an integer 822 if (auto *CE = dyn_cast<MCConstantExpr>(SymRef)) 823 return onInteger(CE->getValue(), ErrMsg); 824 PrevState = State; 825 switch (State) { 826 default: 827 State = IES_ERROR; 828 break; 829 case IES_CAST: 830 case IES_PLUS: 831 case IES_MINUS: 832 case IES_NOT: 833 case IES_INIT: 834 case IES_LBRAC: 835 case IES_LPAREN: 836 if (setSymRef(SymRef, SymRefName, ErrMsg)) 837 return true; 838 MemExpr = true; 839 State = IES_INTEGER; 840 IC.pushOperand(IC_IMM); 841 if (ParsingMSInlineAsm) 842 Info = IDInfo; 843 setTypeInfo(Type); 844 break; 845 } 846 return false; 847 } 848 bool onInteger(int64_t TmpInt, StringRef &ErrMsg) { 849 IntelExprState CurrState = State; 850 switch (State) { 851 default: 852 State = IES_ERROR; 853 break; 854 case IES_PLUS: 855 case IES_MINUS: 856 case IES_NOT: 857 case IES_OR: 858 case IES_XOR: 859 case IES_AND: 860 case IES_EQ: 861 case IES_NE: 862 case IES_LT: 863 case IES_LE: 864 case IES_GT: 865 case IES_GE: 866 case IES_LSHIFT: 867 case IES_RSHIFT: 868 case IES_DIVIDE: 869 case IES_MOD: 870 case IES_MULTIPLY: 871 case IES_LPAREN: 872 case IES_INIT: 873 case IES_LBRAC: 874 State = IES_INTEGER; 875 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) { 876 // Index Register - Register * Scale 877 if (IndexReg) 878 return regsUseUpError(ErrMsg); 879 IndexReg = TmpReg; 880 Scale = TmpInt; 881 if (checkScale(Scale, ErrMsg)) 882 return true; 883 // Get the scale and replace the 'Register * Scale' with '0'. 884 IC.popOperator(); 885 } else { 886 IC.pushOperand(IC_IMM, TmpInt); 887 } 888 break; 889 } 890 PrevState = CurrState; 891 return false; 892 } 893 void onStar() { 894 PrevState = State; 895 switch (State) { 896 default: 897 State = IES_ERROR; 898 break; 899 case IES_INTEGER: 900 case IES_REGISTER: 901 case IES_RPAREN: 902 State = IES_MULTIPLY; 903 IC.pushOperator(IC_MULTIPLY); 904 break; 905 } 906 } 907 void onDivide() { 908 PrevState = State; 909 switch (State) { 910 default: 911 State = IES_ERROR; 912 break; 913 case IES_INTEGER: 914 case IES_RPAREN: 915 State = IES_DIVIDE; 916 IC.pushOperator(IC_DIVIDE); 917 break; 918 } 919 } 920 void onMod() { 921 PrevState = State; 922 switch (State) { 923 default: 924 State = IES_ERROR; 925 break; 926 case IES_INTEGER: 927 case IES_RPAREN: 928 State = IES_MOD; 929 IC.pushOperator(IC_MOD); 930 break; 931 } 932 } 933 bool onLBrac() { 934 if (BracCount) 935 return true; 936 PrevState = State; 937 switch (State) { 938 default: 939 State = IES_ERROR; 940 break; 941 case IES_RBRAC: 942 case IES_INTEGER: 943 case IES_RPAREN: 944 State = IES_PLUS; 945 IC.pushOperator(IC_PLUS); 946 CurType.Length = 1; 947 CurType.Size = CurType.ElementSize; 948 break; 949 case IES_INIT: 950 case IES_CAST: 951 assert(!BracCount && "BracCount should be zero on parsing's start"); 952 State = IES_LBRAC; 953 break; 954 } 955 MemExpr = true; 956 BracCount++; 957 return false; 958 } 959 bool onRBrac(StringRef &ErrMsg) { 960 IntelExprState CurrState = State; 961 switch (State) { 962 default: 963 State = IES_ERROR; 964 break; 965 case IES_INTEGER: 966 case IES_OFFSET: 967 case IES_REGISTER: 968 case IES_RPAREN: 969 if (BracCount-- != 1) { 970 ErrMsg = "unexpected bracket encountered"; 971 return true; 972 } 973 State = IES_RBRAC; 974 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) { 975 // If we already have a BaseReg, then assume this is the IndexReg with 976 // no explicit scale. 977 if (!BaseReg) { 978 BaseReg = TmpReg; 979 } else { 980 if (IndexReg) 981 return regsUseUpError(ErrMsg); 982 IndexReg = TmpReg; 983 Scale = 0; 984 } 985 } 986 break; 987 } 988 PrevState = CurrState; 989 return false; 990 } 991 void onLParen() { 992 IntelExprState CurrState = State; 993 switch (State) { 994 default: 995 State = IES_ERROR; 996 break; 997 case IES_PLUS: 998 case IES_MINUS: 999 case IES_NOT: 1000 case IES_OR: 1001 case IES_XOR: 1002 case IES_AND: 1003 case IES_EQ: 1004 case IES_NE: 1005 case IES_LT: 1006 case IES_LE: 1007 case IES_GT: 1008 case IES_GE: 1009 case IES_LSHIFT: 1010 case IES_RSHIFT: 1011 case IES_MULTIPLY: 1012 case IES_DIVIDE: 1013 case IES_MOD: 1014 case IES_LPAREN: 1015 case IES_INIT: 1016 case IES_LBRAC: 1017 State = IES_LPAREN; 1018 IC.pushOperator(IC_LPAREN); 1019 break; 1020 } 1021 PrevState = CurrState; 1022 } 1023 void onRParen() { 1024 PrevState = State; 1025 switch (State) { 1026 default: 1027 State = IES_ERROR; 1028 break; 1029 case IES_INTEGER: 1030 case IES_OFFSET: 1031 case IES_REGISTER: 1032 case IES_RBRAC: 1033 case IES_RPAREN: 1034 State = IES_RPAREN; 1035 IC.pushOperator(IC_RPAREN); 1036 break; 1037 } 1038 } 1039 bool onOffset(const MCExpr *Val, SMLoc OffsetLoc, StringRef ID, 1040 const InlineAsmIdentifierInfo &IDInfo, 1041 bool ParsingMSInlineAsm, StringRef &ErrMsg) { 1042 PrevState = State; 1043 switch (State) { 1044 default: 1045 ErrMsg = "unexpected offset operator expression"; 1046 return true; 1047 case IES_PLUS: 1048 case IES_INIT: 1049 case IES_LBRAC: 1050 if (setSymRef(Val, ID, ErrMsg)) 1051 return true; 1052 OffsetOperator = true; 1053 OffsetOperatorLoc = OffsetLoc; 1054 State = IES_OFFSET; 1055 // As we cannot yet resolve the actual value (offset), we retain 1056 // the requested semantics by pushing a '0' to the operands stack 1057 IC.pushOperand(IC_IMM); 1058 if (ParsingMSInlineAsm) { 1059 Info = IDInfo; 1060 } 1061 break; 1062 } 1063 return false; 1064 } 1065 void onCast(AsmTypeInfo Info) { 1066 PrevState = State; 1067 switch (State) { 1068 default: 1069 State = IES_ERROR; 1070 break; 1071 case IES_LPAREN: 1072 setTypeInfo(Info); 1073 State = IES_CAST; 1074 break; 1075 } 1076 } 1077 void setTypeInfo(AsmTypeInfo Type) { CurType = Type; } 1078 }; 1079 1080 bool Error(SMLoc L, const Twine &Msg, SMRange Range = None, 1081 bool MatchingInlineAsm = false) { 1082 MCAsmParser &Parser = getParser(); 1083 if (MatchingInlineAsm) { 1084 if (!getLexer().isAtStartOfStatement()) 1085 Parser.eatToEndOfStatement(); 1086 return false; 1087 } 1088 return Parser.Error(L, Msg, Range); 1089 } 1090 1091 bool MatchRegisterByName(unsigned &RegNo, StringRef RegName, SMLoc StartLoc, 1092 SMLoc EndLoc); 1093 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc, 1094 bool RestoreOnFailure); 1095 1096 std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc); 1097 std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc); 1098 bool IsSIReg(unsigned Reg); 1099 unsigned GetSIDIForRegClass(unsigned RegClassID, unsigned Reg, bool IsSIReg); 1100 void 1101 AddDefaultSrcDestOperands(OperandVector &Operands, 1102 std::unique_ptr<llvm::MCParsedAsmOperand> &&Src, 1103 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst); 1104 bool VerifyAndAdjustOperands(OperandVector &OrigOperands, 1105 OperandVector &FinalOperands); 1106 bool parseOperand(OperandVector &Operands, StringRef Name); 1107 bool parseATTOperand(OperandVector &Operands); 1108 bool parseIntelOperand(OperandVector &Operands, StringRef Name); 1109 bool ParseIntelOffsetOperator(const MCExpr *&Val, StringRef &ID, 1110 InlineAsmIdentifierInfo &Info, SMLoc &End); 1111 bool ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End); 1112 unsigned IdentifyIntelInlineAsmOperator(StringRef Name); 1113 unsigned ParseIntelInlineAsmOperator(unsigned OpKind); 1114 unsigned IdentifyMasmOperator(StringRef Name); 1115 bool ParseMasmOperator(unsigned OpKind, int64_t &Val); 1116 bool ParseRoundingModeOp(SMLoc Start, OperandVector &Operands); 1117 bool ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM, 1118 bool &ParseError, SMLoc &End); 1119 bool ParseMasmNamedOperator(StringRef Name, IntelExprStateMachine &SM, 1120 bool &ParseError, SMLoc &End); 1121 void RewriteIntelExpression(IntelExprStateMachine &SM, SMLoc Start, 1122 SMLoc End); 1123 bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End); 1124 bool ParseIntelInlineAsmIdentifier(const MCExpr *&Val, StringRef &Identifier, 1125 InlineAsmIdentifierInfo &Info, 1126 bool IsUnevaluatedOperand, SMLoc &End, 1127 bool IsParsingOffsetOperator = false); 1128 void tryParseOperandIdx(AsmToken::TokenKind PrevTK, 1129 IntelExprStateMachine &SM); 1130 1131 bool ParseMemOperand(unsigned SegReg, const MCExpr *Disp, SMLoc StartLoc, 1132 SMLoc EndLoc, OperandVector &Operands); 1133 1134 X86::CondCode ParseConditionCode(StringRef CCode); 1135 1136 bool ParseIntelMemoryOperandSize(unsigned &Size); 1137 bool CreateMemForMSInlineAsm(unsigned SegReg, const MCExpr *Disp, 1138 unsigned BaseReg, unsigned IndexReg, 1139 unsigned Scale, SMLoc Start, SMLoc End, 1140 unsigned Size, StringRef Identifier, 1141 const InlineAsmIdentifierInfo &Info, 1142 OperandVector &Operands); 1143 1144 bool parseDirectiveArch(); 1145 bool parseDirectiveNops(SMLoc L); 1146 bool parseDirectiveEven(SMLoc L); 1147 bool ParseDirectiveCode(StringRef IDVal, SMLoc L); 1148 1149 /// CodeView FPO data directives. 1150 bool parseDirectiveFPOProc(SMLoc L); 1151 bool parseDirectiveFPOSetFrame(SMLoc L); 1152 bool parseDirectiveFPOPushReg(SMLoc L); 1153 bool parseDirectiveFPOStackAlloc(SMLoc L); 1154 bool parseDirectiveFPOStackAlign(SMLoc L); 1155 bool parseDirectiveFPOEndPrologue(SMLoc L); 1156 bool parseDirectiveFPOEndProc(SMLoc L); 1157 1158 /// SEH directives. 1159 bool parseSEHRegisterNumber(unsigned RegClassID, unsigned &RegNo); 1160 bool parseDirectiveSEHPushReg(SMLoc); 1161 bool parseDirectiveSEHSetFrame(SMLoc); 1162 bool parseDirectiveSEHSaveReg(SMLoc); 1163 bool parseDirectiveSEHSaveXMM(SMLoc); 1164 bool parseDirectiveSEHPushFrame(SMLoc); 1165 1166 unsigned checkTargetMatchPredicate(MCInst &Inst) override; 1167 1168 bool validateInstruction(MCInst &Inst, const OperandVector &Ops); 1169 bool processInstruction(MCInst &Inst, const OperandVector &Ops); 1170 1171 // Load Value Injection (LVI) Mitigations for machine code 1172 void emitWarningForSpecialLVIInstruction(SMLoc Loc); 1173 void applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out); 1174 void applyLVILoadHardeningMitigation(MCInst &Inst, MCStreamer &Out); 1175 1176 /// Wrapper around MCStreamer::emitInstruction(). Possibly adds 1177 /// instrumentation around Inst. 1178 void emitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out); 1179 1180 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 1181 OperandVector &Operands, MCStreamer &Out, 1182 uint64_t &ErrorInfo, 1183 bool MatchingInlineAsm) override; 1184 1185 void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, OperandVector &Operands, 1186 MCStreamer &Out, bool MatchingInlineAsm); 1187 1188 bool ErrorMissingFeature(SMLoc IDLoc, const FeatureBitset &MissingFeatures, 1189 bool MatchingInlineAsm); 1190 1191 bool MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode, 1192 OperandVector &Operands, MCStreamer &Out, 1193 uint64_t &ErrorInfo, 1194 bool MatchingInlineAsm); 1195 1196 bool MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode, 1197 OperandVector &Operands, MCStreamer &Out, 1198 uint64_t &ErrorInfo, 1199 bool MatchingInlineAsm); 1200 1201 bool OmitRegisterFromClobberLists(unsigned RegNo) override; 1202 1203 /// Parses AVX512 specific operand primitives: masked registers ({%k<NUM>}, {z}) 1204 /// and memory broadcasting ({1to<NUM>}) primitives, updating Operands vector if required. 1205 /// return false if no parsing errors occurred, true otherwise. 1206 bool HandleAVX512Operand(OperandVector &Operands); 1207 1208 bool ParseZ(std::unique_ptr<X86Operand> &Z, const SMLoc &StartLoc); 1209 1210 bool is64BitMode() const { 1211 // FIXME: Can tablegen auto-generate this? 1212 return getSTI().getFeatureBits()[X86::Is64Bit]; 1213 } 1214 bool is32BitMode() const { 1215 // FIXME: Can tablegen auto-generate this? 1216 return getSTI().getFeatureBits()[X86::Is32Bit]; 1217 } 1218 bool is16BitMode() const { 1219 // FIXME: Can tablegen auto-generate this? 1220 return getSTI().getFeatureBits()[X86::Is16Bit]; 1221 } 1222 void SwitchMode(unsigned mode) { 1223 MCSubtargetInfo &STI = copySTI(); 1224 FeatureBitset AllModes({X86::Is64Bit, X86::Is32Bit, X86::Is16Bit}); 1225 FeatureBitset OldMode = STI.getFeatureBits() & AllModes; 1226 FeatureBitset FB = ComputeAvailableFeatures( 1227 STI.ToggleFeature(OldMode.flip(mode))); 1228 setAvailableFeatures(FB); 1229 1230 assert(FeatureBitset({mode}) == (STI.getFeatureBits() & AllModes)); 1231 } 1232 1233 unsigned getPointerWidth() { 1234 if (is16BitMode()) return 16; 1235 if (is32BitMode()) return 32; 1236 if (is64BitMode()) return 64; 1237 llvm_unreachable("invalid mode"); 1238 } 1239 1240 bool isParsingIntelSyntax() { 1241 return getParser().getAssemblerDialect(); 1242 } 1243 1244 /// @name Auto-generated Matcher Functions 1245 /// { 1246 1247 #define GET_ASSEMBLER_HEADER 1248 #include "X86GenAsmMatcher.inc" 1249 1250 /// } 1251 1252 public: 1253 enum X86MatchResultTy { 1254 Match_Unsupported = FIRST_TARGET_MATCH_RESULT_TY, 1255 #define GET_OPERAND_DIAGNOSTIC_TYPES 1256 #include "X86GenAsmMatcher.inc" 1257 }; 1258 1259 X86AsmParser(const MCSubtargetInfo &sti, MCAsmParser &Parser, 1260 const MCInstrInfo &mii, const MCTargetOptions &Options) 1261 : MCTargetAsmParser(Options, sti, mii), InstInfo(nullptr), 1262 Code16GCC(false) { 1263 1264 Parser.addAliasForDirective(".word", ".2byte"); 1265 1266 // Initialize the set of available features. 1267 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits())); 1268 } 1269 1270 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 1271 OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc, 1272 SMLoc &EndLoc) override; 1273 1274 bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) override; 1275 1276 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 1277 SMLoc NameLoc, OperandVector &Operands) override; 1278 1279 bool ParseDirective(AsmToken DirectiveID) override; 1280 }; 1281 } // end anonymous namespace 1282 1283 /// @name Auto-generated Match Functions 1284 /// { 1285 1286 static unsigned MatchRegisterName(StringRef Name); 1287 1288 /// } 1289 1290 static bool CheckBaseRegAndIndexRegAndScale(unsigned BaseReg, unsigned IndexReg, 1291 unsigned Scale, bool Is64BitMode, 1292 StringRef &ErrMsg) { 1293 // If we have both a base register and an index register make sure they are 1294 // both 64-bit or 32-bit registers. 1295 // To support VSIB, IndexReg can be 128-bit or 256-bit registers. 1296 1297 if (BaseReg != 0 && 1298 !(BaseReg == X86::RIP || BaseReg == X86::EIP || 1299 X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) || 1300 X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) || 1301 X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg))) { 1302 ErrMsg = "invalid base+index expression"; 1303 return true; 1304 } 1305 1306 if (IndexReg != 0 && 1307 !(IndexReg == X86::EIZ || IndexReg == X86::RIZ || 1308 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) || 1309 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) || 1310 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg) || 1311 X86MCRegisterClasses[X86::VR128XRegClassID].contains(IndexReg) || 1312 X86MCRegisterClasses[X86::VR256XRegClassID].contains(IndexReg) || 1313 X86MCRegisterClasses[X86::VR512RegClassID].contains(IndexReg))) { 1314 ErrMsg = "invalid base+index expression"; 1315 return true; 1316 } 1317 1318 if (((BaseReg == X86::RIP || BaseReg == X86::EIP) && IndexReg != 0) || 1319 IndexReg == X86::EIP || IndexReg == X86::RIP || 1320 IndexReg == X86::ESP || IndexReg == X86::RSP) { 1321 ErrMsg = "invalid base+index expression"; 1322 return true; 1323 } 1324 1325 // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed, 1326 // and then only in non-64-bit modes. 1327 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) && 1328 (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP && 1329 BaseReg != X86::SI && BaseReg != X86::DI))) { 1330 ErrMsg = "invalid 16-bit base register"; 1331 return true; 1332 } 1333 1334 if (BaseReg == 0 && 1335 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) { 1336 ErrMsg = "16-bit memory operand may not include only index register"; 1337 return true; 1338 } 1339 1340 if (BaseReg != 0 && IndexReg != 0) { 1341 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) && 1342 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) || 1343 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) || 1344 IndexReg == X86::EIZ)) { 1345 ErrMsg = "base register is 64-bit, but index register is not"; 1346 return true; 1347 } 1348 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) && 1349 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) || 1350 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg) || 1351 IndexReg == X86::RIZ)) { 1352 ErrMsg = "base register is 32-bit, but index register is not"; 1353 return true; 1354 } 1355 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) { 1356 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) || 1357 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) { 1358 ErrMsg = "base register is 16-bit, but index register is not"; 1359 return true; 1360 } 1361 if ((BaseReg != X86::BX && BaseReg != X86::BP) || 1362 (IndexReg != X86::SI && IndexReg != X86::DI)) { 1363 ErrMsg = "invalid 16-bit base/index register combination"; 1364 return true; 1365 } 1366 } 1367 } 1368 1369 // RIP/EIP-relative addressing is only supported in 64-bit mode. 1370 if (!Is64BitMode && BaseReg != 0 && 1371 (BaseReg == X86::RIP || BaseReg == X86::EIP)) { 1372 ErrMsg = "IP-relative addressing requires 64-bit mode"; 1373 return true; 1374 } 1375 1376 return checkScale(Scale, ErrMsg); 1377 } 1378 1379 bool X86AsmParser::MatchRegisterByName(unsigned &RegNo, StringRef RegName, 1380 SMLoc StartLoc, SMLoc EndLoc) { 1381 // If we encounter a %, ignore it. This code handles registers with and 1382 // without the prefix, unprefixed registers can occur in cfi directives. 1383 RegName.consume_front("%"); 1384 1385 RegNo = MatchRegisterName(RegName); 1386 1387 // If the match failed, try the register name as lowercase. 1388 if (RegNo == 0) 1389 RegNo = MatchRegisterName(RegName.lower()); 1390 1391 // The "flags" and "mxcsr" registers cannot be referenced directly. 1392 // Treat it as an identifier instead. 1393 if (isParsingMSInlineAsm() && isParsingIntelSyntax() && 1394 (RegNo == X86::EFLAGS || RegNo == X86::MXCSR)) 1395 RegNo = 0; 1396 1397 if (!is64BitMode()) { 1398 // FIXME: This should be done using Requires<Not64BitMode> and 1399 // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also 1400 // checked. 1401 if (RegNo == X86::RIZ || RegNo == X86::RIP || 1402 X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) || 1403 X86II::isX86_64NonExtLowByteReg(RegNo) || 1404 X86II::isX86_64ExtendedReg(RegNo)) { 1405 return Error(StartLoc, 1406 "register %" + RegName + " is only available in 64-bit mode", 1407 SMRange(StartLoc, EndLoc)); 1408 } 1409 } 1410 1411 // If this is "db[0-15]", match it as an alias 1412 // for dr[0-15]. 1413 if (RegNo == 0 && RegName.startswith("db")) { 1414 if (RegName.size() == 3) { 1415 switch (RegName[2]) { 1416 case '0': 1417 RegNo = X86::DR0; 1418 break; 1419 case '1': 1420 RegNo = X86::DR1; 1421 break; 1422 case '2': 1423 RegNo = X86::DR2; 1424 break; 1425 case '3': 1426 RegNo = X86::DR3; 1427 break; 1428 case '4': 1429 RegNo = X86::DR4; 1430 break; 1431 case '5': 1432 RegNo = X86::DR5; 1433 break; 1434 case '6': 1435 RegNo = X86::DR6; 1436 break; 1437 case '7': 1438 RegNo = X86::DR7; 1439 break; 1440 case '8': 1441 RegNo = X86::DR8; 1442 break; 1443 case '9': 1444 RegNo = X86::DR9; 1445 break; 1446 } 1447 } else if (RegName.size() == 4 && RegName[2] == '1') { 1448 switch (RegName[3]) { 1449 case '0': 1450 RegNo = X86::DR10; 1451 break; 1452 case '1': 1453 RegNo = X86::DR11; 1454 break; 1455 case '2': 1456 RegNo = X86::DR12; 1457 break; 1458 case '3': 1459 RegNo = X86::DR13; 1460 break; 1461 case '4': 1462 RegNo = X86::DR14; 1463 break; 1464 case '5': 1465 RegNo = X86::DR15; 1466 break; 1467 } 1468 } 1469 } 1470 1471 if (RegNo == 0) { 1472 if (isParsingIntelSyntax()) 1473 return true; 1474 return Error(StartLoc, "invalid register name", SMRange(StartLoc, EndLoc)); 1475 } 1476 return false; 1477 } 1478 1479 bool X86AsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 1480 SMLoc &EndLoc, bool RestoreOnFailure) { 1481 MCAsmParser &Parser = getParser(); 1482 MCAsmLexer &Lexer = getLexer(); 1483 RegNo = 0; 1484 1485 SmallVector<AsmToken, 5> Tokens; 1486 auto OnFailure = [RestoreOnFailure, &Lexer, &Tokens]() { 1487 if (RestoreOnFailure) { 1488 while (!Tokens.empty()) { 1489 Lexer.UnLex(Tokens.pop_back_val()); 1490 } 1491 } 1492 }; 1493 1494 const AsmToken &PercentTok = Parser.getTok(); 1495 StartLoc = PercentTok.getLoc(); 1496 1497 // If we encounter a %, ignore it. This code handles registers with and 1498 // without the prefix, unprefixed registers can occur in cfi directives. 1499 if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent)) { 1500 Tokens.push_back(PercentTok); 1501 Parser.Lex(); // Eat percent token. 1502 } 1503 1504 const AsmToken &Tok = Parser.getTok(); 1505 EndLoc = Tok.getEndLoc(); 1506 1507 if (Tok.isNot(AsmToken::Identifier)) { 1508 OnFailure(); 1509 if (isParsingIntelSyntax()) return true; 1510 return Error(StartLoc, "invalid register name", 1511 SMRange(StartLoc, EndLoc)); 1512 } 1513 1514 if (MatchRegisterByName(RegNo, Tok.getString(), StartLoc, EndLoc)) { 1515 OnFailure(); 1516 return true; 1517 } 1518 1519 // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens. 1520 if (RegNo == X86::ST0) { 1521 Tokens.push_back(Tok); 1522 Parser.Lex(); // Eat 'st' 1523 1524 // Check to see if we have '(4)' after %st. 1525 if (Lexer.isNot(AsmToken::LParen)) 1526 return false; 1527 // Lex the paren. 1528 Tokens.push_back(Parser.getTok()); 1529 Parser.Lex(); 1530 1531 const AsmToken &IntTok = Parser.getTok(); 1532 if (IntTok.isNot(AsmToken::Integer)) { 1533 OnFailure(); 1534 return Error(IntTok.getLoc(), "expected stack index"); 1535 } 1536 switch (IntTok.getIntVal()) { 1537 case 0: RegNo = X86::ST0; break; 1538 case 1: RegNo = X86::ST1; break; 1539 case 2: RegNo = X86::ST2; break; 1540 case 3: RegNo = X86::ST3; break; 1541 case 4: RegNo = X86::ST4; break; 1542 case 5: RegNo = X86::ST5; break; 1543 case 6: RegNo = X86::ST6; break; 1544 case 7: RegNo = X86::ST7; break; 1545 default: 1546 OnFailure(); 1547 return Error(IntTok.getLoc(), "invalid stack index"); 1548 } 1549 1550 // Lex IntTok 1551 Tokens.push_back(IntTok); 1552 Parser.Lex(); 1553 if (Lexer.isNot(AsmToken::RParen)) { 1554 OnFailure(); 1555 return Error(Parser.getTok().getLoc(), "expected ')'"); 1556 } 1557 1558 EndLoc = Parser.getTok().getEndLoc(); 1559 Parser.Lex(); // Eat ')' 1560 return false; 1561 } 1562 1563 EndLoc = Parser.getTok().getEndLoc(); 1564 1565 if (RegNo == 0) { 1566 OnFailure(); 1567 if (isParsingIntelSyntax()) return true; 1568 return Error(StartLoc, "invalid register name", 1569 SMRange(StartLoc, EndLoc)); 1570 } 1571 1572 Parser.Lex(); // Eat identifier token. 1573 return false; 1574 } 1575 1576 bool X86AsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 1577 SMLoc &EndLoc) { 1578 return ParseRegister(RegNo, StartLoc, EndLoc, /*RestoreOnFailure=*/false); 1579 } 1580 1581 OperandMatchResultTy X86AsmParser::tryParseRegister(unsigned &RegNo, 1582 SMLoc &StartLoc, 1583 SMLoc &EndLoc) { 1584 bool Result = 1585 ParseRegister(RegNo, StartLoc, EndLoc, /*RestoreOnFailure=*/true); 1586 bool PendingErrors = getParser().hasPendingError(); 1587 getParser().clearPendingErrors(); 1588 if (PendingErrors) 1589 return MatchOperand_ParseFail; 1590 if (Result) 1591 return MatchOperand_NoMatch; 1592 return MatchOperand_Success; 1593 } 1594 1595 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) { 1596 bool Parse32 = is32BitMode() || Code16GCC; 1597 unsigned Basereg = is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI); 1598 const MCExpr *Disp = MCConstantExpr::create(0, getContext()); 1599 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp, 1600 /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1, 1601 Loc, Loc, 0); 1602 } 1603 1604 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) { 1605 bool Parse32 = is32BitMode() || Code16GCC; 1606 unsigned Basereg = is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI); 1607 const MCExpr *Disp = MCConstantExpr::create(0, getContext()); 1608 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp, 1609 /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1, 1610 Loc, Loc, 0); 1611 } 1612 1613 bool X86AsmParser::IsSIReg(unsigned Reg) { 1614 switch (Reg) { 1615 default: llvm_unreachable("Only (R|E)SI and (R|E)DI are expected!"); 1616 case X86::RSI: 1617 case X86::ESI: 1618 case X86::SI: 1619 return true; 1620 case X86::RDI: 1621 case X86::EDI: 1622 case X86::DI: 1623 return false; 1624 } 1625 } 1626 1627 unsigned X86AsmParser::GetSIDIForRegClass(unsigned RegClassID, unsigned Reg, 1628 bool IsSIReg) { 1629 switch (RegClassID) { 1630 default: llvm_unreachable("Unexpected register class"); 1631 case X86::GR64RegClassID: 1632 return IsSIReg ? X86::RSI : X86::RDI; 1633 case X86::GR32RegClassID: 1634 return IsSIReg ? X86::ESI : X86::EDI; 1635 case X86::GR16RegClassID: 1636 return IsSIReg ? X86::SI : X86::DI; 1637 } 1638 } 1639 1640 void X86AsmParser::AddDefaultSrcDestOperands( 1641 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src, 1642 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) { 1643 if (isParsingIntelSyntax()) { 1644 Operands.push_back(std::move(Dst)); 1645 Operands.push_back(std::move(Src)); 1646 } 1647 else { 1648 Operands.push_back(std::move(Src)); 1649 Operands.push_back(std::move(Dst)); 1650 } 1651 } 1652 1653 bool X86AsmParser::VerifyAndAdjustOperands(OperandVector &OrigOperands, 1654 OperandVector &FinalOperands) { 1655 1656 if (OrigOperands.size() > 1) { 1657 // Check if sizes match, OrigOperands also contains the instruction name 1658 assert(OrigOperands.size() == FinalOperands.size() + 1 && 1659 "Operand size mismatch"); 1660 1661 SmallVector<std::pair<SMLoc, std::string>, 2> Warnings; 1662 // Verify types match 1663 int RegClassID = -1; 1664 for (unsigned int i = 0; i < FinalOperands.size(); ++i) { 1665 X86Operand &OrigOp = static_cast<X86Operand &>(*OrigOperands[i + 1]); 1666 X86Operand &FinalOp = static_cast<X86Operand &>(*FinalOperands[i]); 1667 1668 if (FinalOp.isReg() && 1669 (!OrigOp.isReg() || FinalOp.getReg() != OrigOp.getReg())) 1670 // Return false and let a normal complaint about bogus operands happen 1671 return false; 1672 1673 if (FinalOp.isMem()) { 1674 1675 if (!OrigOp.isMem()) 1676 // Return false and let a normal complaint about bogus operands happen 1677 return false; 1678 1679 unsigned OrigReg = OrigOp.Mem.BaseReg; 1680 unsigned FinalReg = FinalOp.Mem.BaseReg; 1681 1682 // If we've already encounterd a register class, make sure all register 1683 // bases are of the same register class 1684 if (RegClassID != -1 && 1685 !X86MCRegisterClasses[RegClassID].contains(OrigReg)) { 1686 return Error(OrigOp.getStartLoc(), 1687 "mismatching source and destination index registers"); 1688 } 1689 1690 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(OrigReg)) 1691 RegClassID = X86::GR64RegClassID; 1692 else if (X86MCRegisterClasses[X86::GR32RegClassID].contains(OrigReg)) 1693 RegClassID = X86::GR32RegClassID; 1694 else if (X86MCRegisterClasses[X86::GR16RegClassID].contains(OrigReg)) 1695 RegClassID = X86::GR16RegClassID; 1696 else 1697 // Unexpected register class type 1698 // Return false and let a normal complaint about bogus operands happen 1699 return false; 1700 1701 bool IsSI = IsSIReg(FinalReg); 1702 FinalReg = GetSIDIForRegClass(RegClassID, FinalReg, IsSI); 1703 1704 if (FinalReg != OrigReg) { 1705 std::string RegName = IsSI ? "ES:(R|E)SI" : "ES:(R|E)DI"; 1706 Warnings.push_back(std::make_pair( 1707 OrigOp.getStartLoc(), 1708 "memory operand is only for determining the size, " + RegName + 1709 " will be used for the location")); 1710 } 1711 1712 FinalOp.Mem.Size = OrigOp.Mem.Size; 1713 FinalOp.Mem.SegReg = OrigOp.Mem.SegReg; 1714 FinalOp.Mem.BaseReg = FinalReg; 1715 } 1716 } 1717 1718 // Produce warnings only if all the operands passed the adjustment - prevent 1719 // legal cases like "movsd (%rax), %xmm0" mistakenly produce warnings 1720 for (auto &WarningMsg : Warnings) { 1721 Warning(WarningMsg.first, WarningMsg.second); 1722 } 1723 1724 // Remove old operands 1725 for (unsigned int i = 0; i < FinalOperands.size(); ++i) 1726 OrigOperands.pop_back(); 1727 } 1728 // OrigOperands.append(FinalOperands.begin(), FinalOperands.end()); 1729 for (unsigned int i = 0; i < FinalOperands.size(); ++i) 1730 OrigOperands.push_back(std::move(FinalOperands[i])); 1731 1732 return false; 1733 } 1734 1735 bool X86AsmParser::parseOperand(OperandVector &Operands, StringRef Name) { 1736 if (isParsingIntelSyntax()) 1737 return parseIntelOperand(Operands, Name); 1738 1739 return parseATTOperand(Operands); 1740 } 1741 1742 bool X86AsmParser::CreateMemForMSInlineAsm( 1743 unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg, 1744 unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier, 1745 const InlineAsmIdentifierInfo &Info, OperandVector &Operands) { 1746 // If we found a decl other than a VarDecl, then assume it is a FuncDecl or 1747 // some other label reference. 1748 if (Info.isKind(InlineAsmIdentifierInfo::IK_Label)) { 1749 // Insert an explicit size if the user didn't have one. 1750 if (!Size) { 1751 Size = getPointerWidth(); 1752 InstInfo->AsmRewrites->emplace_back(AOK_SizeDirective, Start, 1753 /*Len=*/0, Size); 1754 } 1755 // Create an absolute memory reference in order to match against 1756 // instructions taking a PC relative operand. 1757 Operands.push_back(X86Operand::CreateMem(getPointerWidth(), Disp, Start, 1758 End, Size, Identifier, 1759 Info.Label.Decl)); 1760 return false; 1761 } 1762 // We either have a direct symbol reference, or an offset from a symbol. The 1763 // parser always puts the symbol on the LHS, so look there for size 1764 // calculation purposes. 1765 unsigned FrontendSize = 0; 1766 void *Decl = nullptr; 1767 bool IsGlobalLV = false; 1768 if (Info.isKind(InlineAsmIdentifierInfo::IK_Var)) { 1769 // Size is in terms of bits in this context. 1770 FrontendSize = Info.Var.Type * 8; 1771 Decl = Info.Var.Decl; 1772 IsGlobalLV = Info.Var.IsGlobalLV; 1773 } 1774 // It is widely common for MS InlineAsm to use a global variable and one/two 1775 // registers in a mmory expression, and though unaccessible via rip/eip. 1776 if (IsGlobalLV && (BaseReg || IndexReg)) { 1777 Operands.push_back(X86Operand::CreateMem(getPointerWidth(), Disp, Start, 1778 End, Size, Identifier, Decl, 0, 1779 BaseReg && IndexReg)); 1780 return false; 1781 } 1782 // Otherwise, we set the base register to a non-zero value 1783 // if we don't know the actual value at this time. This is necessary to 1784 // get the matching correct in some cases. 1785 BaseReg = BaseReg ? BaseReg : 1; 1786 Operands.push_back(X86Operand::CreateMem( 1787 getPointerWidth(), SegReg, Disp, BaseReg, IndexReg, Scale, Start, End, 1788 Size, 1789 /*DefaultBaseReg=*/X86::RIP, Identifier, Decl, FrontendSize)); 1790 return false; 1791 } 1792 1793 // Some binary bitwise operators have a named synonymous 1794 // Query a candidate string for being such a named operator 1795 // and if so - invoke the appropriate handler 1796 bool X86AsmParser::ParseIntelNamedOperator(StringRef Name, 1797 IntelExprStateMachine &SM, 1798 bool &ParseError, SMLoc &End) { 1799 // A named operator should be either lower or upper case, but not a mix... 1800 // except in MASM, which uses full case-insensitivity. 1801 if (Name.compare(Name.lower()) && Name.compare(Name.upper()) && 1802 !getParser().isParsingMasm()) 1803 return false; 1804 if (Name.equals_insensitive("not")) { 1805 SM.onNot(); 1806 } else if (Name.equals_insensitive("or")) { 1807 SM.onOr(); 1808 } else if (Name.equals_insensitive("shl")) { 1809 SM.onLShift(); 1810 } else if (Name.equals_insensitive("shr")) { 1811 SM.onRShift(); 1812 } else if (Name.equals_insensitive("xor")) { 1813 SM.onXor(); 1814 } else if (Name.equals_insensitive("and")) { 1815 SM.onAnd(); 1816 } else if (Name.equals_insensitive("mod")) { 1817 SM.onMod(); 1818 } else if (Name.equals_insensitive("offset")) { 1819 SMLoc OffsetLoc = getTok().getLoc(); 1820 const MCExpr *Val = nullptr; 1821 StringRef ID; 1822 InlineAsmIdentifierInfo Info; 1823 ParseError = ParseIntelOffsetOperator(Val, ID, Info, End); 1824 if (ParseError) 1825 return true; 1826 StringRef ErrMsg; 1827 ParseError = 1828 SM.onOffset(Val, OffsetLoc, ID, Info, isParsingMSInlineAsm(), ErrMsg); 1829 if (ParseError) 1830 return Error(SMLoc::getFromPointer(Name.data()), ErrMsg); 1831 } else { 1832 return false; 1833 } 1834 if (!Name.equals_insensitive("offset")) 1835 End = consumeToken(); 1836 return true; 1837 } 1838 bool X86AsmParser::ParseMasmNamedOperator(StringRef Name, 1839 IntelExprStateMachine &SM, 1840 bool &ParseError, SMLoc &End) { 1841 if (Name.equals_insensitive("eq")) { 1842 SM.onEq(); 1843 } else if (Name.equals_insensitive("ne")) { 1844 SM.onNE(); 1845 } else if (Name.equals_insensitive("lt")) { 1846 SM.onLT(); 1847 } else if (Name.equals_insensitive("le")) { 1848 SM.onLE(); 1849 } else if (Name.equals_insensitive("gt")) { 1850 SM.onGT(); 1851 } else if (Name.equals_insensitive("ge")) { 1852 SM.onGE(); 1853 } else { 1854 return false; 1855 } 1856 End = consumeToken(); 1857 return true; 1858 } 1859 1860 // Check if current intel expression append after an operand. 1861 // Like: [Operand][Intel Expression] 1862 void X86AsmParser::tryParseOperandIdx(AsmToken::TokenKind PrevTK, 1863 IntelExprStateMachine &SM) { 1864 if (PrevTK != AsmToken::RBrac) 1865 return; 1866 1867 SM.setAppendAfterOperand(); 1868 } 1869 1870 bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) { 1871 MCAsmParser &Parser = getParser(); 1872 StringRef ErrMsg; 1873 1874 AsmToken::TokenKind PrevTK = AsmToken::Error; 1875 1876 if (getContext().getObjectFileInfo()->isPositionIndependent()) 1877 SM.setPIC(); 1878 1879 bool Done = false; 1880 while (!Done) { 1881 // Get a fresh reference on each loop iteration in case the previous 1882 // iteration moved the token storage during UnLex(). 1883 const AsmToken &Tok = Parser.getTok(); 1884 1885 bool UpdateLocLex = true; 1886 AsmToken::TokenKind TK = getLexer().getKind(); 1887 1888 switch (TK) { 1889 default: 1890 if ((Done = SM.isValidEndState())) 1891 break; 1892 return Error(Tok.getLoc(), "unknown token in expression"); 1893 case AsmToken::Error: 1894 return Error(getLexer().getErrLoc(), getLexer().getErr()); 1895 break; 1896 case AsmToken::EndOfStatement: 1897 Done = true; 1898 break; 1899 case AsmToken::Real: 1900 // DotOperator: [ebx].0 1901 UpdateLocLex = false; 1902 if (ParseIntelDotOperator(SM, End)) 1903 return true; 1904 break; 1905 case AsmToken::Dot: 1906 if (!Parser.isParsingMasm()) { 1907 if ((Done = SM.isValidEndState())) 1908 break; 1909 return Error(Tok.getLoc(), "unknown token in expression"); 1910 } 1911 // MASM allows spaces around the dot operator (e.g., "var . x") 1912 Lex(); 1913 UpdateLocLex = false; 1914 if (ParseIntelDotOperator(SM, End)) 1915 return true; 1916 break; 1917 case AsmToken::Dollar: 1918 if (!Parser.isParsingMasm()) { 1919 if ((Done = SM.isValidEndState())) 1920 break; 1921 return Error(Tok.getLoc(), "unknown token in expression"); 1922 } 1923 LLVM_FALLTHROUGH; 1924 case AsmToken::String: { 1925 if (Parser.isParsingMasm()) { 1926 // MASM parsers handle strings in expressions as constants. 1927 SMLoc ValueLoc = Tok.getLoc(); 1928 int64_t Res; 1929 const MCExpr *Val; 1930 if (Parser.parsePrimaryExpr(Val, End, nullptr)) 1931 return true; 1932 UpdateLocLex = false; 1933 if (!Val->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr())) 1934 return Error(ValueLoc, "expected absolute value"); 1935 if (SM.onInteger(Res, ErrMsg)) 1936 return Error(ValueLoc, ErrMsg); 1937 break; 1938 } 1939 LLVM_FALLTHROUGH; 1940 } 1941 case AsmToken::At: 1942 case AsmToken::Identifier: { 1943 SMLoc IdentLoc = Tok.getLoc(); 1944 StringRef Identifier = Tok.getString(); 1945 UpdateLocLex = false; 1946 if (Parser.isParsingMasm()) { 1947 size_t DotOffset = Identifier.find_first_of('.'); 1948 if (DotOffset != StringRef::npos) { 1949 consumeToken(); 1950 StringRef LHS = Identifier.slice(0, DotOffset); 1951 StringRef Dot = Identifier.slice(DotOffset, DotOffset + 1); 1952 StringRef RHS = Identifier.slice(DotOffset + 1, StringRef::npos); 1953 if (!RHS.empty()) { 1954 getLexer().UnLex(AsmToken(AsmToken::Identifier, RHS)); 1955 } 1956 getLexer().UnLex(AsmToken(AsmToken::Dot, Dot)); 1957 if (!LHS.empty()) { 1958 getLexer().UnLex(AsmToken(AsmToken::Identifier, LHS)); 1959 } 1960 break; 1961 } 1962 } 1963 // (MASM only) <TYPE> PTR operator 1964 if (Parser.isParsingMasm()) { 1965 const AsmToken &NextTok = getLexer().peekTok(); 1966 if (NextTok.is(AsmToken::Identifier) && 1967 NextTok.getIdentifier().equals_insensitive("ptr")) { 1968 AsmTypeInfo Info; 1969 if (Parser.lookUpType(Identifier, Info)) 1970 return Error(Tok.getLoc(), "unknown type"); 1971 SM.onCast(Info); 1972 // Eat type and PTR. 1973 consumeToken(); 1974 End = consumeToken(); 1975 break; 1976 } 1977 } 1978 // Register, or (MASM only) <register>.<field> 1979 unsigned Reg; 1980 if (Tok.is(AsmToken::Identifier)) { 1981 if (!ParseRegister(Reg, IdentLoc, End, /*RestoreOnFailure=*/true)) { 1982 if (SM.onRegister(Reg, ErrMsg)) 1983 return Error(IdentLoc, ErrMsg); 1984 break; 1985 } 1986 if (Parser.isParsingMasm()) { 1987 const std::pair<StringRef, StringRef> IDField = 1988 Tok.getString().split('.'); 1989 const StringRef ID = IDField.first, Field = IDField.second; 1990 SMLoc IDEndLoc = SMLoc::getFromPointer(ID.data() + ID.size()); 1991 if (!Field.empty() && 1992 !MatchRegisterByName(Reg, ID, IdentLoc, IDEndLoc)) { 1993 if (SM.onRegister(Reg, ErrMsg)) 1994 return Error(IdentLoc, ErrMsg); 1995 1996 AsmFieldInfo Info; 1997 SMLoc FieldStartLoc = SMLoc::getFromPointer(Field.data()); 1998 if (Parser.lookUpField(Field, Info)) 1999 return Error(FieldStartLoc, "unknown offset"); 2000 else if (SM.onPlus(ErrMsg)) 2001 return Error(getTok().getLoc(), ErrMsg); 2002 else if (SM.onInteger(Info.Offset, ErrMsg)) 2003 return Error(IdentLoc, ErrMsg); 2004 SM.setTypeInfo(Info.Type); 2005 2006 End = consumeToken(); 2007 break; 2008 } 2009 } 2010 } 2011 // Operator synonymous ("not", "or" etc.) 2012 bool ParseError = false; 2013 if (ParseIntelNamedOperator(Identifier, SM, ParseError, End)) { 2014 if (ParseError) 2015 return true; 2016 break; 2017 } 2018 if (Parser.isParsingMasm() && 2019 ParseMasmNamedOperator(Identifier, SM, ParseError, End)) { 2020 if (ParseError) 2021 return true; 2022 break; 2023 } 2024 // Symbol reference, when parsing assembly content 2025 InlineAsmIdentifierInfo Info; 2026 AsmFieldInfo FieldInfo; 2027 const MCExpr *Val; 2028 if (isParsingMSInlineAsm() || Parser.isParsingMasm()) { 2029 // MS Dot Operator expression 2030 if (Identifier.count('.') && 2031 (PrevTK == AsmToken::RBrac || PrevTK == AsmToken::RParen)) { 2032 if (ParseIntelDotOperator(SM, End)) 2033 return true; 2034 break; 2035 } 2036 } 2037 if (isParsingMSInlineAsm()) { 2038 // MS InlineAsm operators (TYPE/LENGTH/SIZE) 2039 if (unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) { 2040 if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) { 2041 if (SM.onInteger(Val, ErrMsg)) 2042 return Error(IdentLoc, ErrMsg); 2043 } else { 2044 return true; 2045 } 2046 break; 2047 } 2048 // MS InlineAsm identifier 2049 // Call parseIdentifier() to combine @ with the identifier behind it. 2050 if (TK == AsmToken::At && Parser.parseIdentifier(Identifier)) 2051 return Error(IdentLoc, "expected identifier"); 2052 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info, false, End)) 2053 return true; 2054 else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.Type, 2055 true, ErrMsg)) 2056 return Error(IdentLoc, ErrMsg); 2057 break; 2058 } 2059 if (Parser.isParsingMasm()) { 2060 if (unsigned OpKind = IdentifyMasmOperator(Identifier)) { 2061 int64_t Val; 2062 if (ParseMasmOperator(OpKind, Val)) 2063 return true; 2064 if (SM.onInteger(Val, ErrMsg)) 2065 return Error(IdentLoc, ErrMsg); 2066 break; 2067 } 2068 if (!getParser().lookUpType(Identifier, FieldInfo.Type)) { 2069 // Field offset immediate; <TYPE>.<field specification> 2070 Lex(); // eat type 2071 bool EndDot = parseOptionalToken(AsmToken::Dot); 2072 while (EndDot || (getTok().is(AsmToken::Identifier) && 2073 getTok().getString().startswith("."))) { 2074 getParser().parseIdentifier(Identifier); 2075 if (!EndDot) 2076 Identifier.consume_front("."); 2077 EndDot = Identifier.consume_back("."); 2078 if (getParser().lookUpField(FieldInfo.Type.Name, Identifier, 2079 FieldInfo)) { 2080 SMLoc IDEnd = 2081 SMLoc::getFromPointer(Identifier.data() + Identifier.size()); 2082 return Error(IdentLoc, "Unable to lookup field reference!", 2083 SMRange(IdentLoc, IDEnd)); 2084 } 2085 if (!EndDot) 2086 EndDot = parseOptionalToken(AsmToken::Dot); 2087 } 2088 if (SM.onInteger(FieldInfo.Offset, ErrMsg)) 2089 return Error(IdentLoc, ErrMsg); 2090 break; 2091 } 2092 } 2093 if (getParser().parsePrimaryExpr(Val, End, &FieldInfo.Type)) { 2094 return Error(Tok.getLoc(), "Unexpected identifier!"); 2095 } else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.Type, 2096 false, ErrMsg)) { 2097 return Error(IdentLoc, ErrMsg); 2098 } 2099 break; 2100 } 2101 case AsmToken::Integer: { 2102 // Look for 'b' or 'f' following an Integer as a directional label 2103 SMLoc Loc = getTok().getLoc(); 2104 int64_t IntVal = getTok().getIntVal(); 2105 End = consumeToken(); 2106 UpdateLocLex = false; 2107 if (getLexer().getKind() == AsmToken::Identifier) { 2108 StringRef IDVal = getTok().getString(); 2109 if (IDVal == "f" || IDVal == "b") { 2110 MCSymbol *Sym = 2111 getContext().getDirectionalLocalSymbol(IntVal, IDVal == "b"); 2112 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 2113 const MCExpr *Val = 2114 MCSymbolRefExpr::create(Sym, Variant, getContext()); 2115 if (IDVal == "b" && Sym->isUndefined()) 2116 return Error(Loc, "invalid reference to undefined symbol"); 2117 StringRef Identifier = Sym->getName(); 2118 InlineAsmIdentifierInfo Info; 2119 AsmTypeInfo Type; 2120 if (SM.onIdentifierExpr(Val, Identifier, Info, Type, 2121 isParsingMSInlineAsm(), ErrMsg)) 2122 return Error(Loc, ErrMsg); 2123 End = consumeToken(); 2124 } else { 2125 if (SM.onInteger(IntVal, ErrMsg)) 2126 return Error(Loc, ErrMsg); 2127 } 2128 } else { 2129 if (SM.onInteger(IntVal, ErrMsg)) 2130 return Error(Loc, ErrMsg); 2131 } 2132 break; 2133 } 2134 case AsmToken::Plus: 2135 if (SM.onPlus(ErrMsg)) 2136 return Error(getTok().getLoc(), ErrMsg); 2137 break; 2138 case AsmToken::Minus: 2139 if (SM.onMinus(ErrMsg)) 2140 return Error(getTok().getLoc(), ErrMsg); 2141 break; 2142 case AsmToken::Tilde: SM.onNot(); break; 2143 case AsmToken::Star: SM.onStar(); break; 2144 case AsmToken::Slash: SM.onDivide(); break; 2145 case AsmToken::Percent: SM.onMod(); break; 2146 case AsmToken::Pipe: SM.onOr(); break; 2147 case AsmToken::Caret: SM.onXor(); break; 2148 case AsmToken::Amp: SM.onAnd(); break; 2149 case AsmToken::LessLess: 2150 SM.onLShift(); break; 2151 case AsmToken::GreaterGreater: 2152 SM.onRShift(); break; 2153 case AsmToken::LBrac: 2154 if (SM.onLBrac()) 2155 return Error(Tok.getLoc(), "unexpected bracket encountered"); 2156 tryParseOperandIdx(PrevTK, SM); 2157 break; 2158 case AsmToken::RBrac: 2159 if (SM.onRBrac(ErrMsg)) { 2160 return Error(Tok.getLoc(), ErrMsg); 2161 } 2162 break; 2163 case AsmToken::LParen: SM.onLParen(); break; 2164 case AsmToken::RParen: SM.onRParen(); break; 2165 } 2166 if (SM.hadError()) 2167 return Error(Tok.getLoc(), "unknown token in expression"); 2168 2169 if (!Done && UpdateLocLex) 2170 End = consumeToken(); 2171 2172 PrevTK = TK; 2173 } 2174 return false; 2175 } 2176 2177 void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &SM, 2178 SMLoc Start, SMLoc End) { 2179 SMLoc Loc = Start; 2180 unsigned ExprLen = End.getPointer() - Start.getPointer(); 2181 // Skip everything before a symbol displacement (if we have one) 2182 if (SM.getSym() && !SM.isOffsetOperator()) { 2183 StringRef SymName = SM.getSymName(); 2184 if (unsigned Len = SymName.data() - Start.getPointer()) 2185 InstInfo->AsmRewrites->emplace_back(AOK_Skip, Start, Len); 2186 Loc = SMLoc::getFromPointer(SymName.data() + SymName.size()); 2187 ExprLen = End.getPointer() - (SymName.data() + SymName.size()); 2188 // If we have only a symbol than there's no need for complex rewrite, 2189 // simply skip everything after it 2190 if (!(SM.getBaseReg() || SM.getIndexReg() || SM.getImm())) { 2191 if (ExprLen) 2192 InstInfo->AsmRewrites->emplace_back(AOK_Skip, Loc, ExprLen); 2193 return; 2194 } 2195 } 2196 // Build an Intel Expression rewrite 2197 StringRef BaseRegStr; 2198 StringRef IndexRegStr; 2199 StringRef OffsetNameStr; 2200 if (SM.getBaseReg()) 2201 BaseRegStr = X86IntelInstPrinter::getRegisterName(SM.getBaseReg()); 2202 if (SM.getIndexReg()) 2203 IndexRegStr = X86IntelInstPrinter::getRegisterName(SM.getIndexReg()); 2204 if (SM.isOffsetOperator()) 2205 OffsetNameStr = SM.getSymName(); 2206 // Emit it 2207 IntelExpr Expr(BaseRegStr, IndexRegStr, SM.getScale(), OffsetNameStr, 2208 SM.getImm(), SM.isMemExpr()); 2209 InstInfo->AsmRewrites->emplace_back(Loc, ExprLen, Expr); 2210 } 2211 2212 // Inline assembly may use variable names with namespace alias qualifiers. 2213 bool X86AsmParser::ParseIntelInlineAsmIdentifier( 2214 const MCExpr *&Val, StringRef &Identifier, InlineAsmIdentifierInfo &Info, 2215 bool IsUnevaluatedOperand, SMLoc &End, bool IsParsingOffsetOperator) { 2216 MCAsmParser &Parser = getParser(); 2217 assert(isParsingMSInlineAsm() && "Expected to be parsing inline assembly."); 2218 Val = nullptr; 2219 2220 StringRef LineBuf(Identifier.data()); 2221 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand); 2222 2223 const AsmToken &Tok = Parser.getTok(); 2224 SMLoc Loc = Tok.getLoc(); 2225 2226 // Advance the token stream until the end of the current token is 2227 // after the end of what the frontend claimed. 2228 const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size(); 2229 do { 2230 End = Tok.getEndLoc(); 2231 getLexer().Lex(); 2232 } while (End.getPointer() < EndPtr); 2233 Identifier = LineBuf; 2234 2235 // The frontend should end parsing on an assembler token boundary, unless it 2236 // failed parsing. 2237 assert((End.getPointer() == EndPtr || 2238 Info.isKind(InlineAsmIdentifierInfo::IK_Invalid)) && 2239 "frontend claimed part of a token?"); 2240 2241 // If the identifier lookup was unsuccessful, assume that we are dealing with 2242 // a label. 2243 if (Info.isKind(InlineAsmIdentifierInfo::IK_Invalid)) { 2244 StringRef InternalName = 2245 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(), 2246 Loc, false); 2247 assert(InternalName.size() && "We should have an internal name here."); 2248 // Push a rewrite for replacing the identifier name with the internal name, 2249 // unless we are parsing the operand of an offset operator 2250 if (!IsParsingOffsetOperator) 2251 InstInfo->AsmRewrites->emplace_back(AOK_Label, Loc, Identifier.size(), 2252 InternalName); 2253 else 2254 Identifier = InternalName; 2255 } else if (Info.isKind(InlineAsmIdentifierInfo::IK_EnumVal)) 2256 return false; 2257 // Create the symbol reference. 2258 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 2259 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 2260 Val = MCSymbolRefExpr::create(Sym, Variant, getParser().getContext()); 2261 return false; 2262 } 2263 2264 //ParseRoundingModeOp - Parse AVX-512 rounding mode operand 2265 bool X86AsmParser::ParseRoundingModeOp(SMLoc Start, OperandVector &Operands) { 2266 MCAsmParser &Parser = getParser(); 2267 const AsmToken &Tok = Parser.getTok(); 2268 // Eat "{" and mark the current place. 2269 const SMLoc consumedToken = consumeToken(); 2270 if (Tok.isNot(AsmToken::Identifier)) 2271 return Error(Tok.getLoc(), "Expected an identifier after {"); 2272 if (Tok.getIdentifier().startswith("r")){ 2273 int rndMode = StringSwitch<int>(Tok.getIdentifier()) 2274 .Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT) 2275 .Case("rd", X86::STATIC_ROUNDING::TO_NEG_INF) 2276 .Case("ru", X86::STATIC_ROUNDING::TO_POS_INF) 2277 .Case("rz", X86::STATIC_ROUNDING::TO_ZERO) 2278 .Default(-1); 2279 if (-1 == rndMode) 2280 return Error(Tok.getLoc(), "Invalid rounding mode."); 2281 Parser.Lex(); // Eat "r*" of r*-sae 2282 if (!getLexer().is(AsmToken::Minus)) 2283 return Error(Tok.getLoc(), "Expected - at this point"); 2284 Parser.Lex(); // Eat "-" 2285 Parser.Lex(); // Eat the sae 2286 if (!getLexer().is(AsmToken::RCurly)) 2287 return Error(Tok.getLoc(), "Expected } at this point"); 2288 SMLoc End = Tok.getEndLoc(); 2289 Parser.Lex(); // Eat "}" 2290 const MCExpr *RndModeOp = 2291 MCConstantExpr::create(rndMode, Parser.getContext()); 2292 Operands.push_back(X86Operand::CreateImm(RndModeOp, Start, End)); 2293 return false; 2294 } 2295 if(Tok.getIdentifier().equals("sae")){ 2296 Parser.Lex(); // Eat the sae 2297 if (!getLexer().is(AsmToken::RCurly)) 2298 return Error(Tok.getLoc(), "Expected } at this point"); 2299 Parser.Lex(); // Eat "}" 2300 Operands.push_back(X86Operand::CreateToken("{sae}", consumedToken)); 2301 return false; 2302 } 2303 return Error(Tok.getLoc(), "unknown token in expression"); 2304 } 2305 2306 /// Parse the '.' operator. 2307 bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &SM, 2308 SMLoc &End) { 2309 const AsmToken &Tok = getTok(); 2310 AsmFieldInfo Info; 2311 2312 // Drop the optional '.'. 2313 StringRef DotDispStr = Tok.getString(); 2314 if (DotDispStr.startswith(".")) 2315 DotDispStr = DotDispStr.drop_front(1); 2316 StringRef TrailingDot; 2317 2318 // .Imm gets lexed as a real. 2319 if (Tok.is(AsmToken::Real)) { 2320 APInt DotDisp; 2321 DotDispStr.getAsInteger(10, DotDisp); 2322 Info.Offset = DotDisp.getZExtValue(); 2323 } else if ((isParsingMSInlineAsm() || getParser().isParsingMasm()) && 2324 Tok.is(AsmToken::Identifier)) { 2325 if (DotDispStr.endswith(".")) { 2326 TrailingDot = DotDispStr.substr(DotDispStr.size() - 1); 2327 DotDispStr = DotDispStr.drop_back(1); 2328 } 2329 const std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.'); 2330 const StringRef Base = BaseMember.first, Member = BaseMember.second; 2331 if (getParser().lookUpField(SM.getType(), DotDispStr, Info) && 2332 getParser().lookUpField(SM.getSymName(), DotDispStr, Info) && 2333 getParser().lookUpField(DotDispStr, Info) && 2334 (!SemaCallback || 2335 SemaCallback->LookupInlineAsmField(Base, Member, Info.Offset))) 2336 return Error(Tok.getLoc(), "Unable to lookup field reference!"); 2337 } else { 2338 return Error(Tok.getLoc(), "Unexpected token type!"); 2339 } 2340 2341 // Eat the DotExpression and update End 2342 End = SMLoc::getFromPointer(DotDispStr.data()); 2343 const char *DotExprEndLoc = DotDispStr.data() + DotDispStr.size(); 2344 while (Tok.getLoc().getPointer() < DotExprEndLoc) 2345 Lex(); 2346 if (!TrailingDot.empty()) 2347 getLexer().UnLex(AsmToken(AsmToken::Dot, TrailingDot)); 2348 SM.addImm(Info.Offset); 2349 SM.setTypeInfo(Info.Type); 2350 return false; 2351 } 2352 2353 /// Parse the 'offset' operator. 2354 /// This operator is used to specify the location of a given operand 2355 bool X86AsmParser::ParseIntelOffsetOperator(const MCExpr *&Val, StringRef &ID, 2356 InlineAsmIdentifierInfo &Info, 2357 SMLoc &End) { 2358 // Eat offset, mark start of identifier. 2359 SMLoc Start = Lex().getLoc(); 2360 ID = getTok().getString(); 2361 if (!isParsingMSInlineAsm()) { 2362 if ((getTok().isNot(AsmToken::Identifier) && 2363 getTok().isNot(AsmToken::String)) || 2364 getParser().parsePrimaryExpr(Val, End, nullptr)) 2365 return Error(Start, "unexpected token!"); 2366 } else if (ParseIntelInlineAsmIdentifier(Val, ID, Info, false, End, true)) { 2367 return Error(Start, "unable to lookup expression"); 2368 } else if (Info.isKind(InlineAsmIdentifierInfo::IK_EnumVal)) { 2369 return Error(Start, "offset operator cannot yet handle constants"); 2370 } 2371 return false; 2372 } 2373 2374 // Query a candidate string for being an Intel assembly operator 2375 // Report back its kind, or IOK_INVALID if does not evaluated as a known one 2376 unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(StringRef Name) { 2377 return StringSwitch<unsigned>(Name) 2378 .Cases("TYPE","type",IOK_TYPE) 2379 .Cases("SIZE","size",IOK_SIZE) 2380 .Cases("LENGTH","length",IOK_LENGTH) 2381 .Default(IOK_INVALID); 2382 } 2383 2384 /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator 2385 /// returns the number of elements in an array. It returns the value 1 for 2386 /// non-array variables. The SIZE operator returns the size of a C or C++ 2387 /// variable. A variable's size is the product of its LENGTH and TYPE. The 2388 /// TYPE operator returns the size of a C or C++ type or variable. If the 2389 /// variable is an array, TYPE returns the size of a single element. 2390 unsigned X86AsmParser::ParseIntelInlineAsmOperator(unsigned OpKind) { 2391 MCAsmParser &Parser = getParser(); 2392 const AsmToken &Tok = Parser.getTok(); 2393 Parser.Lex(); // Eat operator. 2394 2395 const MCExpr *Val = nullptr; 2396 InlineAsmIdentifierInfo Info; 2397 SMLoc Start = Tok.getLoc(), End; 2398 StringRef Identifier = Tok.getString(); 2399 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info, 2400 /*IsUnevaluatedOperand=*/true, End)) 2401 return 0; 2402 2403 if (!Info.isKind(InlineAsmIdentifierInfo::IK_Var)) { 2404 Error(Start, "unable to lookup expression"); 2405 return 0; 2406 } 2407 2408 unsigned CVal = 0; 2409 switch(OpKind) { 2410 default: llvm_unreachable("Unexpected operand kind!"); 2411 case IOK_LENGTH: CVal = Info.Var.Length; break; 2412 case IOK_SIZE: CVal = Info.Var.Size; break; 2413 case IOK_TYPE: CVal = Info.Var.Type; break; 2414 } 2415 2416 return CVal; 2417 } 2418 2419 // Query a candidate string for being an Intel assembly operator 2420 // Report back its kind, or IOK_INVALID if does not evaluated as a known one 2421 unsigned X86AsmParser::IdentifyMasmOperator(StringRef Name) { 2422 return StringSwitch<unsigned>(Name.lower()) 2423 .Case("type", MOK_TYPE) 2424 .Cases("size", "sizeof", MOK_SIZEOF) 2425 .Cases("length", "lengthof", MOK_LENGTHOF) 2426 .Default(MOK_INVALID); 2427 } 2428 2429 /// Parse the 'LENGTHOF', 'SIZEOF', and 'TYPE' operators. The LENGTHOF operator 2430 /// returns the number of elements in an array. It returns the value 1 for 2431 /// non-array variables. The SIZEOF operator returns the size of a type or 2432 /// variable in bytes. A variable's size is the product of its LENGTH and TYPE. 2433 /// The TYPE operator returns the size of a variable. If the variable is an 2434 /// array, TYPE returns the size of a single element. 2435 bool X86AsmParser::ParseMasmOperator(unsigned OpKind, int64_t &Val) { 2436 MCAsmParser &Parser = getParser(); 2437 SMLoc OpLoc = Parser.getTok().getLoc(); 2438 Parser.Lex(); // Eat operator. 2439 2440 Val = 0; 2441 if (OpKind == MOK_SIZEOF || OpKind == MOK_TYPE) { 2442 // Check for SIZEOF(<type>) and TYPE(<type>). 2443 bool InParens = Parser.getTok().is(AsmToken::LParen); 2444 const AsmToken &IDTok = InParens ? getLexer().peekTok() : Parser.getTok(); 2445 AsmTypeInfo Type; 2446 if (IDTok.is(AsmToken::Identifier) && 2447 !Parser.lookUpType(IDTok.getIdentifier(), Type)) { 2448 Val = Type.Size; 2449 2450 // Eat tokens. 2451 if (InParens) 2452 parseToken(AsmToken::LParen); 2453 parseToken(AsmToken::Identifier); 2454 if (InParens) 2455 parseToken(AsmToken::RParen); 2456 } 2457 } 2458 2459 if (!Val) { 2460 IntelExprStateMachine SM; 2461 SMLoc End, Start = Parser.getTok().getLoc(); 2462 if (ParseIntelExpression(SM, End)) 2463 return true; 2464 2465 switch (OpKind) { 2466 default: 2467 llvm_unreachable("Unexpected operand kind!"); 2468 case MOK_SIZEOF: 2469 Val = SM.getSize(); 2470 break; 2471 case MOK_LENGTHOF: 2472 Val = SM.getLength(); 2473 break; 2474 case MOK_TYPE: 2475 Val = SM.getElementSize(); 2476 break; 2477 } 2478 2479 if (!Val) 2480 return Error(OpLoc, "expression has unknown type", SMRange(Start, End)); 2481 } 2482 2483 return false; 2484 } 2485 2486 bool X86AsmParser::ParseIntelMemoryOperandSize(unsigned &Size) { 2487 Size = StringSwitch<unsigned>(getTok().getString()) 2488 .Cases("BYTE", "byte", 8) 2489 .Cases("WORD", "word", 16) 2490 .Cases("DWORD", "dword", 32) 2491 .Cases("FLOAT", "float", 32) 2492 .Cases("LONG", "long", 32) 2493 .Cases("FWORD", "fword", 48) 2494 .Cases("DOUBLE", "double", 64) 2495 .Cases("QWORD", "qword", 64) 2496 .Cases("MMWORD","mmword", 64) 2497 .Cases("XWORD", "xword", 80) 2498 .Cases("TBYTE", "tbyte", 80) 2499 .Cases("XMMWORD", "xmmword", 128) 2500 .Cases("YMMWORD", "ymmword", 256) 2501 .Cases("ZMMWORD", "zmmword", 512) 2502 .Default(0); 2503 if (Size) { 2504 const AsmToken &Tok = Lex(); // Eat operand size (e.g., byte, word). 2505 if (!(Tok.getString().equals("PTR") || Tok.getString().equals("ptr"))) 2506 return Error(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!"); 2507 Lex(); // Eat ptr. 2508 } 2509 return false; 2510 } 2511 2512 bool X86AsmParser::parseIntelOperand(OperandVector &Operands, StringRef Name) { 2513 MCAsmParser &Parser = getParser(); 2514 const AsmToken &Tok = Parser.getTok(); 2515 SMLoc Start, End; 2516 2517 // Parse optional Size directive. 2518 unsigned Size; 2519 if (ParseIntelMemoryOperandSize(Size)) 2520 return true; 2521 bool PtrInOperand = bool(Size); 2522 2523 Start = Tok.getLoc(); 2524 2525 // Rounding mode operand. 2526 if (getLexer().is(AsmToken::LCurly)) 2527 return ParseRoundingModeOp(Start, Operands); 2528 2529 // Register operand. 2530 unsigned RegNo = 0; 2531 if (Tok.is(AsmToken::Identifier) && !ParseRegister(RegNo, Start, End)) { 2532 if (RegNo == X86::RIP) 2533 return Error(Start, "rip can only be used as a base register"); 2534 // A Register followed by ':' is considered a segment override 2535 if (Tok.isNot(AsmToken::Colon)) { 2536 if (PtrInOperand) 2537 return Error(Start, "expected memory operand after 'ptr', " 2538 "found register operand instead"); 2539 Operands.push_back(X86Operand::CreateReg(RegNo, Start, End)); 2540 return false; 2541 } 2542 // An alleged segment override. check if we have a valid segment register 2543 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo)) 2544 return Error(Start, "invalid segment register"); 2545 // Eat ':' and update Start location 2546 Start = Lex().getLoc(); 2547 } 2548 2549 // Immediates and Memory 2550 IntelExprStateMachine SM; 2551 if (ParseIntelExpression(SM, End)) 2552 return true; 2553 2554 if (isParsingMSInlineAsm()) 2555 RewriteIntelExpression(SM, Start, Tok.getLoc()); 2556 2557 int64_t Imm = SM.getImm(); 2558 const MCExpr *Disp = SM.getSym(); 2559 const MCExpr *ImmDisp = MCConstantExpr::create(Imm, getContext()); 2560 if (Disp && Imm) 2561 Disp = MCBinaryExpr::createAdd(Disp, ImmDisp, getContext()); 2562 if (!Disp) 2563 Disp = ImmDisp; 2564 2565 // RegNo != 0 specifies a valid segment register, 2566 // and we are parsing a segment override 2567 if (!SM.isMemExpr() && !RegNo) { 2568 if (isParsingMSInlineAsm() && SM.isOffsetOperator()) { 2569 const InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo(); 2570 if (Info.isKind(InlineAsmIdentifierInfo::IK_Var)) { 2571 // Disp includes the address of a variable; make sure this is recorded 2572 // for later handling. 2573 Operands.push_back(X86Operand::CreateImm(Disp, Start, End, 2574 SM.getSymName(), Info.Var.Decl, 2575 Info.Var.IsGlobalLV)); 2576 return false; 2577 } 2578 } 2579 2580 Operands.push_back(X86Operand::CreateImm(Disp, Start, End)); 2581 return false; 2582 } 2583 2584 StringRef ErrMsg; 2585 unsigned BaseReg = SM.getBaseReg(); 2586 unsigned IndexReg = SM.getIndexReg(); 2587 if (IndexReg && BaseReg == X86::RIP) 2588 BaseReg = 0; 2589 unsigned Scale = SM.getScale(); 2590 if (!PtrInOperand) 2591 Size = SM.getElementSize() << 3; 2592 2593 if (Scale == 0 && BaseReg != X86::ESP && BaseReg != X86::RSP && 2594 (IndexReg == X86::ESP || IndexReg == X86::RSP)) 2595 std::swap(BaseReg, IndexReg); 2596 2597 // If BaseReg is a vector register and IndexReg is not, swap them unless 2598 // Scale was specified in which case it would be an error. 2599 if (Scale == 0 && 2600 !(X86MCRegisterClasses[X86::VR128XRegClassID].contains(IndexReg) || 2601 X86MCRegisterClasses[X86::VR256XRegClassID].contains(IndexReg) || 2602 X86MCRegisterClasses[X86::VR512RegClassID].contains(IndexReg)) && 2603 (X86MCRegisterClasses[X86::VR128XRegClassID].contains(BaseReg) || 2604 X86MCRegisterClasses[X86::VR256XRegClassID].contains(BaseReg) || 2605 X86MCRegisterClasses[X86::VR512RegClassID].contains(BaseReg))) 2606 std::swap(BaseReg, IndexReg); 2607 2608 if (Scale != 0 && 2609 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) 2610 return Error(Start, "16-bit addresses cannot have a scale"); 2611 2612 // If there was no explicit scale specified, change it to 1. 2613 if (Scale == 0) 2614 Scale = 1; 2615 2616 // If this is a 16-bit addressing mode with the base and index in the wrong 2617 // order, swap them so CheckBaseRegAndIndexRegAndScale doesn't fail. It is 2618 // shared with att syntax where order matters. 2619 if ((BaseReg == X86::SI || BaseReg == X86::DI) && 2620 (IndexReg == X86::BX || IndexReg == X86::BP)) 2621 std::swap(BaseReg, IndexReg); 2622 2623 if ((BaseReg || IndexReg) && 2624 CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, is64BitMode(), 2625 ErrMsg)) 2626 return Error(Start, ErrMsg); 2627 if (isParsingMSInlineAsm()) 2628 return CreateMemForMSInlineAsm(RegNo, Disp, BaseReg, IndexReg, Scale, Start, 2629 End, Size, SM.getSymName(), 2630 SM.getIdentifierInfo(), Operands); 2631 2632 // When parsing x64 MS-style assembly, all non-absolute references to a named 2633 // variable default to RIP-relative. 2634 unsigned DefaultBaseReg = X86::NoRegister; 2635 bool MaybeDirectBranchDest = true; 2636 2637 if (Parser.isParsingMasm()) { 2638 bool IsUnconditionalBranch = 2639 Name.equals_insensitive("jmp") || Name.equals_insensitive("call"); 2640 if (is64BitMode() && SM.getElementSize() > 0) { 2641 DefaultBaseReg = X86::RIP; 2642 } 2643 if (IsUnconditionalBranch) { 2644 if (PtrInOperand) { 2645 MaybeDirectBranchDest = false; 2646 if (is64BitMode()) 2647 DefaultBaseReg = X86::RIP; 2648 } else if (!BaseReg && !IndexReg && Disp && 2649 Disp->getKind() == MCExpr::SymbolRef) { 2650 if (is64BitMode()) { 2651 if (SM.getSize() == 8) { 2652 MaybeDirectBranchDest = false; 2653 DefaultBaseReg = X86::RIP; 2654 } 2655 } else { 2656 if (SM.getSize() == 4 || SM.getSize() == 2) 2657 MaybeDirectBranchDest = false; 2658 } 2659 } 2660 } 2661 } 2662 2663 if ((BaseReg || IndexReg || RegNo || DefaultBaseReg != X86::NoRegister)) 2664 Operands.push_back(X86Operand::CreateMem( 2665 getPointerWidth(), RegNo, Disp, BaseReg, IndexReg, Scale, Start, End, 2666 Size, DefaultBaseReg, /*SymName=*/StringRef(), /*OpDecl=*/nullptr, 2667 /*FrontendSize=*/0, /*UseUpRegs=*/false, MaybeDirectBranchDest)); 2668 else 2669 Operands.push_back(X86Operand::CreateMem( 2670 getPointerWidth(), Disp, Start, End, Size, /*SymName=*/StringRef(), 2671 /*OpDecl=*/nullptr, /*FrontendSize=*/0, /*UseUpRegs=*/false, 2672 MaybeDirectBranchDest)); 2673 return false; 2674 } 2675 2676 bool X86AsmParser::parseATTOperand(OperandVector &Operands) { 2677 MCAsmParser &Parser = getParser(); 2678 switch (getLexer().getKind()) { 2679 case AsmToken::Dollar: { 2680 // $42 or $ID -> immediate. 2681 SMLoc Start = Parser.getTok().getLoc(), End; 2682 Parser.Lex(); 2683 const MCExpr *Val; 2684 // This is an immediate, so we should not parse a register. Do a precheck 2685 // for '%' to supercede intra-register parse errors. 2686 SMLoc L = Parser.getTok().getLoc(); 2687 if (check(getLexer().is(AsmToken::Percent), L, 2688 "expected immediate expression") || 2689 getParser().parseExpression(Val, End) || 2690 check(isa<X86MCExpr>(Val), L, "expected immediate expression")) 2691 return true; 2692 Operands.push_back(X86Operand::CreateImm(Val, Start, End)); 2693 return false; 2694 } 2695 case AsmToken::LCurly: { 2696 SMLoc Start = Parser.getTok().getLoc(); 2697 return ParseRoundingModeOp(Start, Operands); 2698 } 2699 default: { 2700 // This a memory operand or a register. We have some parsing complications 2701 // as a '(' may be part of an immediate expression or the addressing mode 2702 // block. This is complicated by the fact that an assembler-level variable 2703 // may refer either to a register or an immediate expression. 2704 2705 SMLoc Loc = Parser.getTok().getLoc(), EndLoc; 2706 const MCExpr *Expr = nullptr; 2707 unsigned Reg = 0; 2708 if (getLexer().isNot(AsmToken::LParen)) { 2709 // No '(' so this is either a displacement expression or a register. 2710 if (Parser.parseExpression(Expr, EndLoc)) 2711 return true; 2712 if (auto *RE = dyn_cast<X86MCExpr>(Expr)) { 2713 // Segment Register. Reset Expr and copy value to register. 2714 Expr = nullptr; 2715 Reg = RE->getRegNo(); 2716 2717 // Check the register. 2718 if (Reg == X86::EIZ || Reg == X86::RIZ) 2719 return Error( 2720 Loc, "%eiz and %riz can only be used as index registers", 2721 SMRange(Loc, EndLoc)); 2722 if (Reg == X86::RIP) 2723 return Error(Loc, "%rip can only be used as a base register", 2724 SMRange(Loc, EndLoc)); 2725 // Return register that are not segment prefixes immediately. 2726 if (!Parser.parseOptionalToken(AsmToken::Colon)) { 2727 Operands.push_back(X86Operand::CreateReg(Reg, Loc, EndLoc)); 2728 return false; 2729 } 2730 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(Reg)) 2731 return Error(Loc, "invalid segment register"); 2732 // Accept a '*' absolute memory reference after the segment. Place it 2733 // before the full memory operand. 2734 if (getLexer().is(AsmToken::Star)) 2735 Operands.push_back(X86Operand::CreateToken("*", consumeToken())); 2736 } 2737 } 2738 // This is a Memory operand. 2739 return ParseMemOperand(Reg, Expr, Loc, EndLoc, Operands); 2740 } 2741 } 2742 } 2743 2744 // X86::COND_INVALID if not a recognized condition code or alternate mnemonic, 2745 // otherwise the EFLAGS Condition Code enumerator. 2746 X86::CondCode X86AsmParser::ParseConditionCode(StringRef CC) { 2747 return StringSwitch<X86::CondCode>(CC) 2748 .Case("o", X86::COND_O) // Overflow 2749 .Case("no", X86::COND_NO) // No Overflow 2750 .Cases("b", "nae", X86::COND_B) // Below/Neither Above nor Equal 2751 .Cases("ae", "nb", X86::COND_AE) // Above or Equal/Not Below 2752 .Cases("e", "z", X86::COND_E) // Equal/Zero 2753 .Cases("ne", "nz", X86::COND_NE) // Not Equal/Not Zero 2754 .Cases("be", "na", X86::COND_BE) // Below or Equal/Not Above 2755 .Cases("a", "nbe", X86::COND_A) // Above/Neither Below nor Equal 2756 .Case("s", X86::COND_S) // Sign 2757 .Case("ns", X86::COND_NS) // No Sign 2758 .Cases("p", "pe", X86::COND_P) // Parity/Parity Even 2759 .Cases("np", "po", X86::COND_NP) // No Parity/Parity Odd 2760 .Cases("l", "nge", X86::COND_L) // Less/Neither Greater nor Equal 2761 .Cases("ge", "nl", X86::COND_GE) // Greater or Equal/Not Less 2762 .Cases("le", "ng", X86::COND_LE) // Less or Equal/Not Greater 2763 .Cases("g", "nle", X86::COND_G) // Greater/Neither Less nor Equal 2764 .Default(X86::COND_INVALID); 2765 } 2766 2767 // true on failure, false otherwise 2768 // If no {z} mark was found - Parser doesn't advance 2769 bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z, 2770 const SMLoc &StartLoc) { 2771 MCAsmParser &Parser = getParser(); 2772 // Assuming we are just pass the '{' mark, quering the next token 2773 // Searched for {z}, but none was found. Return false, as no parsing error was 2774 // encountered 2775 if (!(getLexer().is(AsmToken::Identifier) && 2776 (getLexer().getTok().getIdentifier() == "z"))) 2777 return false; 2778 Parser.Lex(); // Eat z 2779 // Query and eat the '}' mark 2780 if (!getLexer().is(AsmToken::RCurly)) 2781 return Error(getLexer().getLoc(), "Expected } at this point"); 2782 Parser.Lex(); // Eat '}' 2783 // Assign Z with the {z} mark operand 2784 Z = X86Operand::CreateToken("{z}", StartLoc); 2785 return false; 2786 } 2787 2788 // true on failure, false otherwise 2789 bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands) { 2790 MCAsmParser &Parser = getParser(); 2791 if (getLexer().is(AsmToken::LCurly)) { 2792 // Eat "{" and mark the current place. 2793 const SMLoc consumedToken = consumeToken(); 2794 // Distinguish {1to<NUM>} from {%k<NUM>}. 2795 if(getLexer().is(AsmToken::Integer)) { 2796 // Parse memory broadcasting ({1to<NUM>}). 2797 if (getLexer().getTok().getIntVal() != 1) 2798 return TokError("Expected 1to<NUM> at this point"); 2799 StringRef Prefix = getLexer().getTok().getString(); 2800 Parser.Lex(); // Eat first token of 1to8 2801 if (!getLexer().is(AsmToken::Identifier)) 2802 return TokError("Expected 1to<NUM> at this point"); 2803 // Recognize only reasonable suffixes. 2804 SmallVector<char, 5> BroadcastVector; 2805 StringRef BroadcastString = (Prefix + getLexer().getTok().getIdentifier()) 2806 .toStringRef(BroadcastVector); 2807 if (!BroadcastString.startswith("1to")) 2808 return TokError("Expected 1to<NUM> at this point"); 2809 const char *BroadcastPrimitive = 2810 StringSwitch<const char *>(BroadcastString) 2811 .Case("1to2", "{1to2}") 2812 .Case("1to4", "{1to4}") 2813 .Case("1to8", "{1to8}") 2814 .Case("1to16", "{1to16}") 2815 .Case("1to32", "{1to32}") 2816 .Default(nullptr); 2817 if (!BroadcastPrimitive) 2818 return TokError("Invalid memory broadcast primitive."); 2819 Parser.Lex(); // Eat trailing token of 1toN 2820 if (!getLexer().is(AsmToken::RCurly)) 2821 return TokError("Expected } at this point"); 2822 Parser.Lex(); // Eat "}" 2823 Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive, 2824 consumedToken)); 2825 // No AVX512 specific primitives can pass 2826 // after memory broadcasting, so return. 2827 return false; 2828 } else { 2829 // Parse either {k}{z}, {z}{k}, {k} or {z} 2830 // last one have no meaning, but GCC accepts it 2831 // Currently, we're just pass a '{' mark 2832 std::unique_ptr<X86Operand> Z; 2833 if (ParseZ(Z, consumedToken)) 2834 return true; 2835 // Reaching here means that parsing of the allegadly '{z}' mark yielded 2836 // no errors. 2837 // Query for the need of further parsing for a {%k<NUM>} mark 2838 if (!Z || getLexer().is(AsmToken::LCurly)) { 2839 SMLoc StartLoc = Z ? consumeToken() : consumedToken; 2840 // Parse an op-mask register mark ({%k<NUM>}), which is now to be 2841 // expected 2842 unsigned RegNo; 2843 SMLoc RegLoc; 2844 if (!ParseRegister(RegNo, RegLoc, StartLoc) && 2845 X86MCRegisterClasses[X86::VK1RegClassID].contains(RegNo)) { 2846 if (RegNo == X86::K0) 2847 return Error(RegLoc, "Register k0 can't be used as write mask"); 2848 if (!getLexer().is(AsmToken::RCurly)) 2849 return Error(getLexer().getLoc(), "Expected } at this point"); 2850 Operands.push_back(X86Operand::CreateToken("{", StartLoc)); 2851 Operands.push_back( 2852 X86Operand::CreateReg(RegNo, StartLoc, StartLoc)); 2853 Operands.push_back(X86Operand::CreateToken("}", consumeToken())); 2854 } else 2855 return Error(getLexer().getLoc(), 2856 "Expected an op-mask register at this point"); 2857 // {%k<NUM>} mark is found, inquire for {z} 2858 if (getLexer().is(AsmToken::LCurly) && !Z) { 2859 // Have we've found a parsing error, or found no (expected) {z} mark 2860 // - report an error 2861 if (ParseZ(Z, consumeToken()) || !Z) 2862 return Error(getLexer().getLoc(), 2863 "Expected a {z} mark at this point"); 2864 2865 } 2866 // '{z}' on its own is meaningless, hence should be ignored. 2867 // on the contrary - have it been accompanied by a K register, 2868 // allow it. 2869 if (Z) 2870 Operands.push_back(std::move(Z)); 2871 } 2872 } 2873 } 2874 return false; 2875 } 2876 2877 /// ParseMemOperand: 'seg : disp(basereg, indexreg, scale)'. The '%ds:' prefix 2878 /// has already been parsed if present. disp may be provided as well. 2879 bool X86AsmParser::ParseMemOperand(unsigned SegReg, const MCExpr *Disp, 2880 SMLoc StartLoc, SMLoc EndLoc, 2881 OperandVector &Operands) { 2882 MCAsmParser &Parser = getParser(); 2883 SMLoc Loc; 2884 // Based on the initial passed values, we may be in any of these cases, we are 2885 // in one of these cases (with current position (*)): 2886 2887 // 1. seg : * disp (base-index-scale-expr) 2888 // 2. seg : *(disp) (base-index-scale-expr) 2889 // 3. seg : *(base-index-scale-expr) 2890 // 4. disp *(base-index-scale-expr) 2891 // 5. *(disp) (base-index-scale-expr) 2892 // 6. *(base-index-scale-expr) 2893 // 7. disp * 2894 // 8. *(disp) 2895 2896 // If we do not have an displacement yet, check if we're in cases 4 or 6 by 2897 // checking if the first object after the parenthesis is a register (or an 2898 // identifier referring to a register) and parse the displacement or default 2899 // to 0 as appropriate. 2900 auto isAtMemOperand = [this]() { 2901 if (this->getLexer().isNot(AsmToken::LParen)) 2902 return false; 2903 AsmToken Buf[2]; 2904 StringRef Id; 2905 auto TokCount = this->getLexer().peekTokens(Buf, true); 2906 if (TokCount == 0) 2907 return false; 2908 switch (Buf[0].getKind()) { 2909 case AsmToken::Percent: 2910 case AsmToken::Comma: 2911 return true; 2912 // These lower cases are doing a peekIdentifier. 2913 case AsmToken::At: 2914 case AsmToken::Dollar: 2915 if ((TokCount > 1) && 2916 (Buf[1].is(AsmToken::Identifier) || Buf[1].is(AsmToken::String)) && 2917 (Buf[0].getLoc().getPointer() + 1 == Buf[1].getLoc().getPointer())) 2918 Id = StringRef(Buf[0].getLoc().getPointer(), 2919 Buf[1].getIdentifier().size() + 1); 2920 break; 2921 case AsmToken::Identifier: 2922 case AsmToken::String: 2923 Id = Buf[0].getIdentifier(); 2924 break; 2925 default: 2926 return false; 2927 } 2928 // We have an ID. Check if it is bound to a register. 2929 if (!Id.empty()) { 2930 MCSymbol *Sym = this->getContext().getOrCreateSymbol(Id); 2931 if (Sym->isVariable()) { 2932 auto V = Sym->getVariableValue(/*SetUsed*/ false); 2933 return isa<X86MCExpr>(V); 2934 } 2935 } 2936 return false; 2937 }; 2938 2939 if (!Disp) { 2940 // Parse immediate if we're not at a mem operand yet. 2941 if (!isAtMemOperand()) { 2942 if (Parser.parseTokenLoc(Loc) || Parser.parseExpression(Disp, EndLoc)) 2943 return true; 2944 assert(!isa<X86MCExpr>(Disp) && "Expected non-register here."); 2945 } else { 2946 // Disp is implicitly zero if we haven't parsed it yet. 2947 Disp = MCConstantExpr::create(0, Parser.getContext()); 2948 } 2949 } 2950 2951 // We are now either at the end of the operand or at the '(' at the start of a 2952 // base-index-scale-expr. 2953 2954 if (!parseOptionalToken(AsmToken::LParen)) { 2955 if (SegReg == 0) 2956 Operands.push_back( 2957 X86Operand::CreateMem(getPointerWidth(), Disp, StartLoc, EndLoc)); 2958 else 2959 Operands.push_back(X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 2960 0, 0, 1, StartLoc, EndLoc)); 2961 return false; 2962 } 2963 2964 // If we reached here, then eat the '(' and Process 2965 // the rest of the memory operand. 2966 unsigned BaseReg = 0, IndexReg = 0, Scale = 1; 2967 SMLoc BaseLoc = getLexer().getLoc(); 2968 const MCExpr *E; 2969 StringRef ErrMsg; 2970 2971 // Parse BaseReg if one is provided. 2972 if (getLexer().isNot(AsmToken::Comma) && getLexer().isNot(AsmToken::RParen)) { 2973 if (Parser.parseExpression(E, EndLoc) || 2974 check(!isa<X86MCExpr>(E), BaseLoc, "expected register here")) 2975 return true; 2976 2977 // Check the register. 2978 BaseReg = cast<X86MCExpr>(E)->getRegNo(); 2979 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) 2980 return Error(BaseLoc, "eiz and riz can only be used as index registers", 2981 SMRange(BaseLoc, EndLoc)); 2982 } 2983 2984 if (parseOptionalToken(AsmToken::Comma)) { 2985 // Following the comma we should have either an index register, or a scale 2986 // value. We don't support the later form, but we want to parse it 2987 // correctly. 2988 // 2989 // Even though it would be completely consistent to support syntax like 2990 // "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this. 2991 if (getLexer().isNot(AsmToken::RParen)) { 2992 if (Parser.parseTokenLoc(Loc) || Parser.parseExpression(E, EndLoc)) 2993 return true; 2994 2995 if (!isa<X86MCExpr>(E)) { 2996 // We've parsed an unexpected Scale Value instead of an index 2997 // register. Interpret it as an absolute. 2998 int64_t ScaleVal; 2999 if (!E->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr())) 3000 return Error(Loc, "expected absolute expression"); 3001 if (ScaleVal != 1) 3002 Warning(Loc, "scale factor without index register is ignored"); 3003 Scale = 1; 3004 } else { // IndexReg Found. 3005 IndexReg = cast<X86MCExpr>(E)->getRegNo(); 3006 3007 if (BaseReg == X86::RIP) 3008 return Error(Loc, 3009 "%rip as base register can not have an index register"); 3010 if (IndexReg == X86::RIP) 3011 return Error(Loc, "%rip is not allowed as an index register"); 3012 3013 if (parseOptionalToken(AsmToken::Comma)) { 3014 // Parse the scale amount: 3015 // ::= ',' [scale-expression] 3016 3017 // A scale amount without an index is ignored. 3018 if (getLexer().isNot(AsmToken::RParen)) { 3019 int64_t ScaleVal; 3020 if (Parser.parseTokenLoc(Loc) || 3021 Parser.parseAbsoluteExpression(ScaleVal)) 3022 return Error(Loc, "expected scale expression"); 3023 Scale = (unsigned)ScaleVal; 3024 // Validate the scale amount. 3025 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) && 3026 Scale != 1) 3027 return Error(Loc, "scale factor in 16-bit address must be 1"); 3028 if (checkScale(Scale, ErrMsg)) 3029 return Error(Loc, ErrMsg); 3030 } 3031 } 3032 } 3033 } 3034 } 3035 3036 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too. 3037 if (parseToken(AsmToken::RParen, "unexpected token in memory operand")) 3038 return true; 3039 3040 // This is to support otherwise illegal operand (%dx) found in various 3041 // unofficial manuals examples (e.g. "out[s]?[bwl]? %al, (%dx)") and must now 3042 // be supported. Mark such DX variants separately fix only in special cases. 3043 if (BaseReg == X86::DX && IndexReg == 0 && Scale == 1 && SegReg == 0 && 3044 isa<MCConstantExpr>(Disp) && 3045 cast<MCConstantExpr>(Disp)->getValue() == 0) { 3046 Operands.push_back(X86Operand::CreateDXReg(BaseLoc, BaseLoc)); 3047 return false; 3048 } 3049 3050 if (CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, is64BitMode(), 3051 ErrMsg)) 3052 return Error(BaseLoc, ErrMsg); 3053 3054 if (SegReg || BaseReg || IndexReg) 3055 Operands.push_back(X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 3056 BaseReg, IndexReg, Scale, StartLoc, 3057 EndLoc)); 3058 else 3059 Operands.push_back( 3060 X86Operand::CreateMem(getPointerWidth(), Disp, StartLoc, EndLoc)); 3061 return false; 3062 } 3063 3064 // Parse either a standard primary expression or a register. 3065 bool X86AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { 3066 MCAsmParser &Parser = getParser(); 3067 // See if this is a register first. 3068 if (getTok().is(AsmToken::Percent) || 3069 (isParsingIntelSyntax() && getTok().is(AsmToken::Identifier) && 3070 MatchRegisterName(Parser.getTok().getString()))) { 3071 SMLoc StartLoc = Parser.getTok().getLoc(); 3072 unsigned RegNo; 3073 if (ParseRegister(RegNo, StartLoc, EndLoc)) 3074 return true; 3075 Res = X86MCExpr::create(RegNo, Parser.getContext()); 3076 return false; 3077 } 3078 return Parser.parsePrimaryExpr(Res, EndLoc, nullptr); 3079 } 3080 3081 bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 3082 SMLoc NameLoc, OperandVector &Operands) { 3083 MCAsmParser &Parser = getParser(); 3084 InstInfo = &Info; 3085 3086 // Reset the forced VEX encoding. 3087 ForcedVEXEncoding = VEXEncoding_Default; 3088 ForcedDispEncoding = DispEncoding_Default; 3089 3090 // Parse pseudo prefixes. 3091 while (true) { 3092 if (Name == "{") { 3093 if (getLexer().isNot(AsmToken::Identifier)) 3094 return Error(Parser.getTok().getLoc(), "Unexpected token after '{'"); 3095 std::string Prefix = Parser.getTok().getString().lower(); 3096 Parser.Lex(); // Eat identifier. 3097 if (getLexer().isNot(AsmToken::RCurly)) 3098 return Error(Parser.getTok().getLoc(), "Expected '}'"); 3099 Parser.Lex(); // Eat curly. 3100 3101 if (Prefix == "vex") 3102 ForcedVEXEncoding = VEXEncoding_VEX; 3103 else if (Prefix == "vex2") 3104 ForcedVEXEncoding = VEXEncoding_VEX2; 3105 else if (Prefix == "vex3") 3106 ForcedVEXEncoding = VEXEncoding_VEX3; 3107 else if (Prefix == "evex") 3108 ForcedVEXEncoding = VEXEncoding_EVEX; 3109 else if (Prefix == "disp8") 3110 ForcedDispEncoding = DispEncoding_Disp8; 3111 else if (Prefix == "disp32") 3112 ForcedDispEncoding = DispEncoding_Disp32; 3113 else 3114 return Error(NameLoc, "unknown prefix"); 3115 3116 NameLoc = Parser.getTok().getLoc(); 3117 if (getLexer().is(AsmToken::LCurly)) { 3118 Parser.Lex(); 3119 Name = "{"; 3120 } else { 3121 if (getLexer().isNot(AsmToken::Identifier)) 3122 return Error(Parser.getTok().getLoc(), "Expected identifier"); 3123 // FIXME: The mnemonic won't match correctly if its not in lower case. 3124 Name = Parser.getTok().getString(); 3125 Parser.Lex(); 3126 } 3127 continue; 3128 } 3129 // Parse MASM style pseudo prefixes. 3130 if (isParsingMSInlineAsm()) { 3131 if (Name.equals_insensitive("vex")) 3132 ForcedVEXEncoding = VEXEncoding_VEX; 3133 else if (Name.equals_insensitive("vex2")) 3134 ForcedVEXEncoding = VEXEncoding_VEX2; 3135 else if (Name.equals_insensitive("vex3")) 3136 ForcedVEXEncoding = VEXEncoding_VEX3; 3137 else if (Name.equals_insensitive("evex")) 3138 ForcedVEXEncoding = VEXEncoding_EVEX; 3139 3140 if (ForcedVEXEncoding != VEXEncoding_Default) { 3141 if (getLexer().isNot(AsmToken::Identifier)) 3142 return Error(Parser.getTok().getLoc(), "Expected identifier"); 3143 // FIXME: The mnemonic won't match correctly if its not in lower case. 3144 Name = Parser.getTok().getString(); 3145 NameLoc = Parser.getTok().getLoc(); 3146 Parser.Lex(); 3147 } 3148 } 3149 break; 3150 } 3151 3152 // Support the suffix syntax for overriding displacement size as well. 3153 if (Name.consume_back(".d32")) { 3154 ForcedDispEncoding = DispEncoding_Disp32; 3155 } else if (Name.consume_back(".d8")) { 3156 ForcedDispEncoding = DispEncoding_Disp8; 3157 } 3158 3159 StringRef PatchedName = Name; 3160 3161 // Hack to skip "short" following Jcc. 3162 if (isParsingIntelSyntax() && 3163 (PatchedName == "jmp" || PatchedName == "jc" || PatchedName == "jnc" || 3164 PatchedName == "jcxz" || PatchedName == "jecxz" || 3165 (PatchedName.startswith("j") && 3166 ParseConditionCode(PatchedName.substr(1)) != X86::COND_INVALID))) { 3167 StringRef NextTok = Parser.getTok().getString(); 3168 if (Parser.isParsingMasm() ? NextTok.equals_insensitive("short") 3169 : NextTok == "short") { 3170 SMLoc NameEndLoc = 3171 NameLoc.getFromPointer(NameLoc.getPointer() + Name.size()); 3172 // Eat the short keyword. 3173 Parser.Lex(); 3174 // MS and GAS ignore the short keyword; they both determine the jmp type 3175 // based on the distance of the label. (NASM does emit different code with 3176 // and without "short," though.) 3177 InstInfo->AsmRewrites->emplace_back(AOK_Skip, NameEndLoc, 3178 NextTok.size() + 1); 3179 } 3180 } 3181 3182 // FIXME: Hack to recognize setneb as setne. 3183 if (PatchedName.startswith("set") && PatchedName.endswith("b") && 3184 PatchedName != "setb" && PatchedName != "setnb") 3185 PatchedName = PatchedName.substr(0, Name.size()-1); 3186 3187 unsigned ComparisonPredicate = ~0U; 3188 3189 // FIXME: Hack to recognize cmp<comparison code>{sh,ss,sd,ph,ps,pd}. 3190 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) && 3191 (PatchedName.endswith("ss") || PatchedName.endswith("sd") || 3192 PatchedName.endswith("sh") || PatchedName.endswith("ph") || 3193 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) { 3194 bool IsVCMP = PatchedName[0] == 'v'; 3195 unsigned CCIdx = IsVCMP ? 4 : 3; 3196 unsigned CC = StringSwitch<unsigned>( 3197 PatchedName.slice(CCIdx, PatchedName.size() - 2)) 3198 .Case("eq", 0x00) 3199 .Case("eq_oq", 0x00) 3200 .Case("lt", 0x01) 3201 .Case("lt_os", 0x01) 3202 .Case("le", 0x02) 3203 .Case("le_os", 0x02) 3204 .Case("unord", 0x03) 3205 .Case("unord_q", 0x03) 3206 .Case("neq", 0x04) 3207 .Case("neq_uq", 0x04) 3208 .Case("nlt", 0x05) 3209 .Case("nlt_us", 0x05) 3210 .Case("nle", 0x06) 3211 .Case("nle_us", 0x06) 3212 .Case("ord", 0x07) 3213 .Case("ord_q", 0x07) 3214 /* AVX only from here */ 3215 .Case("eq_uq", 0x08) 3216 .Case("nge", 0x09) 3217 .Case("nge_us", 0x09) 3218 .Case("ngt", 0x0A) 3219 .Case("ngt_us", 0x0A) 3220 .Case("false", 0x0B) 3221 .Case("false_oq", 0x0B) 3222 .Case("neq_oq", 0x0C) 3223 .Case("ge", 0x0D) 3224 .Case("ge_os", 0x0D) 3225 .Case("gt", 0x0E) 3226 .Case("gt_os", 0x0E) 3227 .Case("true", 0x0F) 3228 .Case("true_uq", 0x0F) 3229 .Case("eq_os", 0x10) 3230 .Case("lt_oq", 0x11) 3231 .Case("le_oq", 0x12) 3232 .Case("unord_s", 0x13) 3233 .Case("neq_us", 0x14) 3234 .Case("nlt_uq", 0x15) 3235 .Case("nle_uq", 0x16) 3236 .Case("ord_s", 0x17) 3237 .Case("eq_us", 0x18) 3238 .Case("nge_uq", 0x19) 3239 .Case("ngt_uq", 0x1A) 3240 .Case("false_os", 0x1B) 3241 .Case("neq_os", 0x1C) 3242 .Case("ge_oq", 0x1D) 3243 .Case("gt_oq", 0x1E) 3244 .Case("true_us", 0x1F) 3245 .Default(~0U); 3246 if (CC != ~0U && (IsVCMP || CC < 8) && 3247 (IsVCMP || PatchedName.back() != 'h')) { 3248 if (PatchedName.endswith("ss")) 3249 PatchedName = IsVCMP ? "vcmpss" : "cmpss"; 3250 else if (PatchedName.endswith("sd")) 3251 PatchedName = IsVCMP ? "vcmpsd" : "cmpsd"; 3252 else if (PatchedName.endswith("ps")) 3253 PatchedName = IsVCMP ? "vcmpps" : "cmpps"; 3254 else if (PatchedName.endswith("pd")) 3255 PatchedName = IsVCMP ? "vcmppd" : "cmppd"; 3256 else if (PatchedName.endswith("sh")) 3257 PatchedName = "vcmpsh"; 3258 else if (PatchedName.endswith("ph")) 3259 PatchedName = "vcmpph"; 3260 else 3261 llvm_unreachable("Unexpected suffix!"); 3262 3263 ComparisonPredicate = CC; 3264 } 3265 } 3266 3267 // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}. 3268 if (PatchedName.startswith("vpcmp") && 3269 (PatchedName.back() == 'b' || PatchedName.back() == 'w' || 3270 PatchedName.back() == 'd' || PatchedName.back() == 'q')) { 3271 unsigned SuffixSize = PatchedName.drop_back().back() == 'u' ? 2 : 1; 3272 unsigned CC = StringSwitch<unsigned>( 3273 PatchedName.slice(5, PatchedName.size() - SuffixSize)) 3274 .Case("eq", 0x0) // Only allowed on unsigned. Checked below. 3275 .Case("lt", 0x1) 3276 .Case("le", 0x2) 3277 //.Case("false", 0x3) // Not a documented alias. 3278 .Case("neq", 0x4) 3279 .Case("nlt", 0x5) 3280 .Case("nle", 0x6) 3281 //.Case("true", 0x7) // Not a documented alias. 3282 .Default(~0U); 3283 if (CC != ~0U && (CC != 0 || SuffixSize == 2)) { 3284 switch (PatchedName.back()) { 3285 default: llvm_unreachable("Unexpected character!"); 3286 case 'b': PatchedName = SuffixSize == 2 ? "vpcmpub" : "vpcmpb"; break; 3287 case 'w': PatchedName = SuffixSize == 2 ? "vpcmpuw" : "vpcmpw"; break; 3288 case 'd': PatchedName = SuffixSize == 2 ? "vpcmpud" : "vpcmpd"; break; 3289 case 'q': PatchedName = SuffixSize == 2 ? "vpcmpuq" : "vpcmpq"; break; 3290 } 3291 // Set up the immediate to push into the operands later. 3292 ComparisonPredicate = CC; 3293 } 3294 } 3295 3296 // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}. 3297 if (PatchedName.startswith("vpcom") && 3298 (PatchedName.back() == 'b' || PatchedName.back() == 'w' || 3299 PatchedName.back() == 'd' || PatchedName.back() == 'q')) { 3300 unsigned SuffixSize = PatchedName.drop_back().back() == 'u' ? 2 : 1; 3301 unsigned CC = StringSwitch<unsigned>( 3302 PatchedName.slice(5, PatchedName.size() - SuffixSize)) 3303 .Case("lt", 0x0) 3304 .Case("le", 0x1) 3305 .Case("gt", 0x2) 3306 .Case("ge", 0x3) 3307 .Case("eq", 0x4) 3308 .Case("neq", 0x5) 3309 .Case("false", 0x6) 3310 .Case("true", 0x7) 3311 .Default(~0U); 3312 if (CC != ~0U) { 3313 switch (PatchedName.back()) { 3314 default: llvm_unreachable("Unexpected character!"); 3315 case 'b': PatchedName = SuffixSize == 2 ? "vpcomub" : "vpcomb"; break; 3316 case 'w': PatchedName = SuffixSize == 2 ? "vpcomuw" : "vpcomw"; break; 3317 case 'd': PatchedName = SuffixSize == 2 ? "vpcomud" : "vpcomd"; break; 3318 case 'q': PatchedName = SuffixSize == 2 ? "vpcomuq" : "vpcomq"; break; 3319 } 3320 // Set up the immediate to push into the operands later. 3321 ComparisonPredicate = CC; 3322 } 3323 } 3324 3325 3326 // Determine whether this is an instruction prefix. 3327 // FIXME: 3328 // Enhance prefixes integrity robustness. for example, following forms 3329 // are currently tolerated: 3330 // repz repnz <insn> ; GAS errors for the use of two similar prefixes 3331 // lock addq %rax, %rbx ; Destination operand must be of memory type 3332 // xacquire <insn> ; xacquire must be accompanied by 'lock' 3333 bool IsPrefix = 3334 StringSwitch<bool>(Name) 3335 .Cases("cs", "ds", "es", "fs", "gs", "ss", true) 3336 .Cases("rex64", "data32", "data16", "addr32", "addr16", true) 3337 .Cases("xacquire", "xrelease", true) 3338 .Cases("acquire", "release", isParsingIntelSyntax()) 3339 .Default(false); 3340 3341 auto isLockRepeatNtPrefix = [](StringRef N) { 3342 return StringSwitch<bool>(N) 3343 .Cases("lock", "rep", "repe", "repz", "repne", "repnz", "notrack", true) 3344 .Default(false); 3345 }; 3346 3347 bool CurlyAsEndOfStatement = false; 3348 3349 unsigned Flags = X86::IP_NO_PREFIX; 3350 while (isLockRepeatNtPrefix(Name.lower())) { 3351 unsigned Prefix = 3352 StringSwitch<unsigned>(Name) 3353 .Cases("lock", "lock", X86::IP_HAS_LOCK) 3354 .Cases("rep", "repe", "repz", X86::IP_HAS_REPEAT) 3355 .Cases("repne", "repnz", X86::IP_HAS_REPEAT_NE) 3356 .Cases("notrack", "notrack", X86::IP_HAS_NOTRACK) 3357 .Default(X86::IP_NO_PREFIX); // Invalid prefix (impossible) 3358 Flags |= Prefix; 3359 if (getLexer().is(AsmToken::EndOfStatement)) { 3360 // We don't have real instr with the given prefix 3361 // let's use the prefix as the instr. 3362 // TODO: there could be several prefixes one after another 3363 Flags = X86::IP_NO_PREFIX; 3364 break; 3365 } 3366 // FIXME: The mnemonic won't match correctly if its not in lower case. 3367 Name = Parser.getTok().getString(); 3368 Parser.Lex(); // eat the prefix 3369 // Hack: we could have something like "rep # some comment" or 3370 // "lock; cmpxchg16b $1" or "lock\0A\09incl" or "lock/incl" 3371 while (Name.startswith(";") || Name.startswith("\n") || 3372 Name.startswith("#") || Name.startswith("\t") || 3373 Name.startswith("/")) { 3374 // FIXME: The mnemonic won't match correctly if its not in lower case. 3375 Name = Parser.getTok().getString(); 3376 Parser.Lex(); // go to next prefix or instr 3377 } 3378 } 3379 3380 if (Flags) 3381 PatchedName = Name; 3382 3383 // Hacks to handle 'data16' and 'data32' 3384 if (PatchedName == "data16" && is16BitMode()) { 3385 return Error(NameLoc, "redundant data16 prefix"); 3386 } 3387 if (PatchedName == "data32") { 3388 if (is32BitMode()) 3389 return Error(NameLoc, "redundant data32 prefix"); 3390 if (is64BitMode()) 3391 return Error(NameLoc, "'data32' is not supported in 64-bit mode"); 3392 // Hack to 'data16' for the table lookup. 3393 PatchedName = "data16"; 3394 3395 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3396 StringRef Next = Parser.getTok().getString(); 3397 getLexer().Lex(); 3398 // data32 effectively changes the instruction suffix. 3399 // TODO Generalize. 3400 if (Next == "callw") 3401 Next = "calll"; 3402 if (Next == "ljmpw") 3403 Next = "ljmpl"; 3404 3405 Name = Next; 3406 PatchedName = Name; 3407 ForcedDataPrefix = X86::Is32Bit; 3408 IsPrefix = false; 3409 } 3410 } 3411 3412 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc)); 3413 3414 // Push the immediate if we extracted one from the mnemonic. 3415 if (ComparisonPredicate != ~0U && !isParsingIntelSyntax()) { 3416 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonPredicate, 3417 getParser().getContext()); 3418 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc)); 3419 } 3420 3421 // This does the actual operand parsing. Don't parse any more if we have a 3422 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we 3423 // just want to parse the "lock" as the first instruction and the "incl" as 3424 // the next one. 3425 if (getLexer().isNot(AsmToken::EndOfStatement) && !IsPrefix) { 3426 // Parse '*' modifier. 3427 if (getLexer().is(AsmToken::Star)) 3428 Operands.push_back(X86Operand::CreateToken("*", consumeToken())); 3429 3430 // Read the operands. 3431 while (true) { 3432 if (parseOperand(Operands, Name)) 3433 return true; 3434 if (HandleAVX512Operand(Operands)) 3435 return true; 3436 3437 // check for comma and eat it 3438 if (getLexer().is(AsmToken::Comma)) 3439 Parser.Lex(); 3440 else 3441 break; 3442 } 3443 3444 // In MS inline asm curly braces mark the beginning/end of a block, 3445 // therefore they should be interepreted as end of statement 3446 CurlyAsEndOfStatement = 3447 isParsingIntelSyntax() && isParsingMSInlineAsm() && 3448 (getLexer().is(AsmToken::LCurly) || getLexer().is(AsmToken::RCurly)); 3449 if (getLexer().isNot(AsmToken::EndOfStatement) && !CurlyAsEndOfStatement) 3450 return TokError("unexpected token in argument list"); 3451 } 3452 3453 // Push the immediate if we extracted one from the mnemonic. 3454 if (ComparisonPredicate != ~0U && isParsingIntelSyntax()) { 3455 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonPredicate, 3456 getParser().getContext()); 3457 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc)); 3458 } 3459 3460 // Consume the EndOfStatement or the prefix separator Slash 3461 if (getLexer().is(AsmToken::EndOfStatement) || 3462 (IsPrefix && getLexer().is(AsmToken::Slash))) 3463 Parser.Lex(); 3464 else if (CurlyAsEndOfStatement) 3465 // Add an actual EndOfStatement before the curly brace 3466 Info.AsmRewrites->emplace_back(AOK_EndOfStatement, 3467 getLexer().getTok().getLoc(), 0); 3468 3469 // This is for gas compatibility and cannot be done in td. 3470 // Adding "p" for some floating point with no argument. 3471 // For example: fsub --> fsubp 3472 bool IsFp = 3473 Name == "fsub" || Name == "fdiv" || Name == "fsubr" || Name == "fdivr"; 3474 if (IsFp && Operands.size() == 1) { 3475 const char *Repl = StringSwitch<const char *>(Name) 3476 .Case("fsub", "fsubp") 3477 .Case("fdiv", "fdivp") 3478 .Case("fsubr", "fsubrp") 3479 .Case("fdivr", "fdivrp"); 3480 static_cast<X86Operand &>(*Operands[0]).setTokenValue(Repl); 3481 } 3482 3483 if ((Name == "mov" || Name == "movw" || Name == "movl") && 3484 (Operands.size() == 3)) { 3485 X86Operand &Op1 = (X86Operand &)*Operands[1]; 3486 X86Operand &Op2 = (X86Operand &)*Operands[2]; 3487 SMLoc Loc = Op1.getEndLoc(); 3488 // Moving a 32 or 16 bit value into a segment register has the same 3489 // behavior. Modify such instructions to always take shorter form. 3490 if (Op1.isReg() && Op2.isReg() && 3491 X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains( 3492 Op2.getReg()) && 3493 (X86MCRegisterClasses[X86::GR16RegClassID].contains(Op1.getReg()) || 3494 X86MCRegisterClasses[X86::GR32RegClassID].contains(Op1.getReg()))) { 3495 // Change instruction name to match new instruction. 3496 if (Name != "mov" && Name[3] == (is16BitMode() ? 'l' : 'w')) { 3497 Name = is16BitMode() ? "movw" : "movl"; 3498 Operands[0] = X86Operand::CreateToken(Name, NameLoc); 3499 } 3500 // Select the correct equivalent 16-/32-bit source register. 3501 unsigned Reg = 3502 getX86SubSuperRegisterOrZero(Op1.getReg(), is16BitMode() ? 16 : 32); 3503 Operands[1] = X86Operand::CreateReg(Reg, Loc, Loc); 3504 } 3505 } 3506 3507 // This is a terrible hack to handle "out[s]?[bwl]? %al, (%dx)" -> 3508 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely 3509 // documented form in various unofficial manuals, so a lot of code uses it. 3510 if ((Name == "outb" || Name == "outsb" || Name == "outw" || Name == "outsw" || 3511 Name == "outl" || Name == "outsl" || Name == "out" || Name == "outs") && 3512 Operands.size() == 3) { 3513 X86Operand &Op = (X86Operand &)*Operands.back(); 3514 if (Op.isDXReg()) 3515 Operands.back() = X86Operand::CreateReg(X86::DX, Op.getStartLoc(), 3516 Op.getEndLoc()); 3517 } 3518 // Same hack for "in[s]?[bwl]? (%dx), %al" -> "inb %dx, %al". 3519 if ((Name == "inb" || Name == "insb" || Name == "inw" || Name == "insw" || 3520 Name == "inl" || Name == "insl" || Name == "in" || Name == "ins") && 3521 Operands.size() == 3) { 3522 X86Operand &Op = (X86Operand &)*Operands[1]; 3523 if (Op.isDXReg()) 3524 Operands[1] = X86Operand::CreateReg(X86::DX, Op.getStartLoc(), 3525 Op.getEndLoc()); 3526 } 3527 3528 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 2> TmpOperands; 3529 bool HadVerifyError = false; 3530 3531 // Append default arguments to "ins[bwld]" 3532 if (Name.startswith("ins") && 3533 (Operands.size() == 1 || Operands.size() == 3) && 3534 (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd" || 3535 Name == "ins")) { 3536 3537 AddDefaultSrcDestOperands(TmpOperands, 3538 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc), 3539 DefaultMemDIOperand(NameLoc)); 3540 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands); 3541 } 3542 3543 // Append default arguments to "outs[bwld]" 3544 if (Name.startswith("outs") && 3545 (Operands.size() == 1 || Operands.size() == 3) && 3546 (Name == "outsb" || Name == "outsw" || Name == "outsl" || 3547 Name == "outsd" || Name == "outs")) { 3548 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc), 3549 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc)); 3550 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands); 3551 } 3552 3553 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate 3554 // values of $SIREG according to the mode. It would be nice if this 3555 // could be achieved with InstAlias in the tables. 3556 if (Name.startswith("lods") && 3557 (Operands.size() == 1 || Operands.size() == 2) && 3558 (Name == "lods" || Name == "lodsb" || Name == "lodsw" || 3559 Name == "lodsl" || Name == "lodsd" || Name == "lodsq")) { 3560 TmpOperands.push_back(DefaultMemSIOperand(NameLoc)); 3561 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands); 3562 } 3563 3564 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate 3565 // values of $DIREG according to the mode. It would be nice if this 3566 // could be achieved with InstAlias in the tables. 3567 if (Name.startswith("stos") && 3568 (Operands.size() == 1 || Operands.size() == 2) && 3569 (Name == "stos" || Name == "stosb" || Name == "stosw" || 3570 Name == "stosl" || Name == "stosd" || Name == "stosq")) { 3571 TmpOperands.push_back(DefaultMemDIOperand(NameLoc)); 3572 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands); 3573 } 3574 3575 // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate 3576 // values of $DIREG according to the mode. It would be nice if this 3577 // could be achieved with InstAlias in the tables. 3578 if (Name.startswith("scas") && 3579 (Operands.size() == 1 || Operands.size() == 2) && 3580 (Name == "scas" || Name == "scasb" || Name == "scasw" || 3581 Name == "scasl" || Name == "scasd" || Name == "scasq")) { 3582 TmpOperands.push_back(DefaultMemDIOperand(NameLoc)); 3583 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands); 3584 } 3585 3586 // Add default SI and DI operands to "cmps[bwlq]". 3587 if (Name.startswith("cmps") && 3588 (Operands.size() == 1 || Operands.size() == 3) && 3589 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" || 3590 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) { 3591 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc), 3592 DefaultMemSIOperand(NameLoc)); 3593 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands); 3594 } 3595 3596 // Add default SI and DI operands to "movs[bwlq]". 3597 if (((Name.startswith("movs") && 3598 (Name == "movs" || Name == "movsb" || Name == "movsw" || 3599 Name == "movsl" || Name == "movsd" || Name == "movsq")) || 3600 (Name.startswith("smov") && 3601 (Name == "smov" || Name == "smovb" || Name == "smovw" || 3602 Name == "smovl" || Name == "smovd" || Name == "smovq"))) && 3603 (Operands.size() == 1 || Operands.size() == 3)) { 3604 if (Name == "movsd" && Operands.size() == 1 && !isParsingIntelSyntax()) 3605 Operands.back() = X86Operand::CreateToken("movsl", NameLoc); 3606 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc), 3607 DefaultMemDIOperand(NameLoc)); 3608 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands); 3609 } 3610 3611 // Check if we encountered an error for one the string insturctions 3612 if (HadVerifyError) { 3613 return HadVerifyError; 3614 } 3615 3616 // Transforms "xlat mem8" into "xlatb" 3617 if ((Name == "xlat" || Name == "xlatb") && Operands.size() == 2) { 3618 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]); 3619 if (Op1.isMem8()) { 3620 Warning(Op1.getStartLoc(), "memory operand is only for determining the " 3621 "size, (R|E)BX will be used for the location"); 3622 Operands.pop_back(); 3623 static_cast<X86Operand &>(*Operands[0]).setTokenValue("xlatb"); 3624 } 3625 } 3626 3627 if (Flags) 3628 Operands.push_back(X86Operand::CreatePrefix(Flags, NameLoc, NameLoc)); 3629 return false; 3630 } 3631 3632 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) { 3633 const MCRegisterInfo *MRI = getContext().getRegisterInfo(); 3634 3635 switch (Inst.getOpcode()) { 3636 default: return false; 3637 case X86::JMP_1: 3638 // {disp32} forces a larger displacement as if the instruction was relaxed. 3639 // NOTE: 16-bit mode uses 16-bit displacement even though it says {disp32}. 3640 // This matches GNU assembler. 3641 if (ForcedDispEncoding == DispEncoding_Disp32) { 3642 Inst.setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4); 3643 return true; 3644 } 3645 3646 return false; 3647 case X86::JCC_1: 3648 // {disp32} forces a larger displacement as if the instruction was relaxed. 3649 // NOTE: 16-bit mode uses 16-bit displacement even though it says {disp32}. 3650 // This matches GNU assembler. 3651 if (ForcedDispEncoding == DispEncoding_Disp32) { 3652 Inst.setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4); 3653 return true; 3654 } 3655 3656 return false; 3657 case X86::VMOVZPQILo2PQIrr: 3658 case X86::VMOVAPDrr: 3659 case X86::VMOVAPDYrr: 3660 case X86::VMOVAPSrr: 3661 case X86::VMOVAPSYrr: 3662 case X86::VMOVDQArr: 3663 case X86::VMOVDQAYrr: 3664 case X86::VMOVDQUrr: 3665 case X86::VMOVDQUYrr: 3666 case X86::VMOVUPDrr: 3667 case X86::VMOVUPDYrr: 3668 case X86::VMOVUPSrr: 3669 case X86::VMOVUPSYrr: { 3670 // We can get a smaller encoding by using VEX.R instead of VEX.B if one of 3671 // the registers is extended, but other isn't. 3672 if (ForcedVEXEncoding == VEXEncoding_VEX3 || 3673 MRI->getEncodingValue(Inst.getOperand(0).getReg()) >= 8 || 3674 MRI->getEncodingValue(Inst.getOperand(1).getReg()) < 8) 3675 return false; 3676 3677 unsigned NewOpc; 3678 switch (Inst.getOpcode()) { 3679 default: llvm_unreachable("Invalid opcode"); 3680 case X86::VMOVZPQILo2PQIrr: NewOpc = X86::VMOVPQI2QIrr; break; 3681 case X86::VMOVAPDrr: NewOpc = X86::VMOVAPDrr_REV; break; 3682 case X86::VMOVAPDYrr: NewOpc = X86::VMOVAPDYrr_REV; break; 3683 case X86::VMOVAPSrr: NewOpc = X86::VMOVAPSrr_REV; break; 3684 case X86::VMOVAPSYrr: NewOpc = X86::VMOVAPSYrr_REV; break; 3685 case X86::VMOVDQArr: NewOpc = X86::VMOVDQArr_REV; break; 3686 case X86::VMOVDQAYrr: NewOpc = X86::VMOVDQAYrr_REV; break; 3687 case X86::VMOVDQUrr: NewOpc = X86::VMOVDQUrr_REV; break; 3688 case X86::VMOVDQUYrr: NewOpc = X86::VMOVDQUYrr_REV; break; 3689 case X86::VMOVUPDrr: NewOpc = X86::VMOVUPDrr_REV; break; 3690 case X86::VMOVUPDYrr: NewOpc = X86::VMOVUPDYrr_REV; break; 3691 case X86::VMOVUPSrr: NewOpc = X86::VMOVUPSrr_REV; break; 3692 case X86::VMOVUPSYrr: NewOpc = X86::VMOVUPSYrr_REV; break; 3693 } 3694 Inst.setOpcode(NewOpc); 3695 return true; 3696 } 3697 case X86::VMOVSDrr: 3698 case X86::VMOVSSrr: { 3699 // We can get a smaller encoding by using VEX.R instead of VEX.B if one of 3700 // the registers is extended, but other isn't. 3701 if (ForcedVEXEncoding == VEXEncoding_VEX3 || 3702 MRI->getEncodingValue(Inst.getOperand(0).getReg()) >= 8 || 3703 MRI->getEncodingValue(Inst.getOperand(2).getReg()) < 8) 3704 return false; 3705 3706 unsigned NewOpc; 3707 switch (Inst.getOpcode()) { 3708 default: llvm_unreachable("Invalid opcode"); 3709 case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV; break; 3710 case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV; break; 3711 } 3712 Inst.setOpcode(NewOpc); 3713 return true; 3714 } 3715 case X86::RCR8ri: case X86::RCR16ri: case X86::RCR32ri: case X86::RCR64ri: 3716 case X86::RCL8ri: case X86::RCL16ri: case X86::RCL32ri: case X86::RCL64ri: 3717 case X86::ROR8ri: case X86::ROR16ri: case X86::ROR32ri: case X86::ROR64ri: 3718 case X86::ROL8ri: case X86::ROL16ri: case X86::ROL32ri: case X86::ROL64ri: 3719 case X86::SAR8ri: case X86::SAR16ri: case X86::SAR32ri: case X86::SAR64ri: 3720 case X86::SHR8ri: case X86::SHR16ri: case X86::SHR32ri: case X86::SHR64ri: 3721 case X86::SHL8ri: case X86::SHL16ri: case X86::SHL32ri: case X86::SHL64ri: { 3722 // Optimize s{hr,ar,hl} $1, <op> to "shift <op>". Similar for rotate. 3723 // FIXME: It would be great if we could just do this with an InstAlias. 3724 if (!Inst.getOperand(2).isImm() || Inst.getOperand(2).getImm() != 1) 3725 return false; 3726 3727 unsigned NewOpc; 3728 switch (Inst.getOpcode()) { 3729 default: llvm_unreachable("Invalid opcode"); 3730 case X86::RCR8ri: NewOpc = X86::RCR8r1; break; 3731 case X86::RCR16ri: NewOpc = X86::RCR16r1; break; 3732 case X86::RCR32ri: NewOpc = X86::RCR32r1; break; 3733 case X86::RCR64ri: NewOpc = X86::RCR64r1; break; 3734 case X86::RCL8ri: NewOpc = X86::RCL8r1; break; 3735 case X86::RCL16ri: NewOpc = X86::RCL16r1; break; 3736 case X86::RCL32ri: NewOpc = X86::RCL32r1; break; 3737 case X86::RCL64ri: NewOpc = X86::RCL64r1; break; 3738 case X86::ROR8ri: NewOpc = X86::ROR8r1; break; 3739 case X86::ROR16ri: NewOpc = X86::ROR16r1; break; 3740 case X86::ROR32ri: NewOpc = X86::ROR32r1; break; 3741 case X86::ROR64ri: NewOpc = X86::ROR64r1; break; 3742 case X86::ROL8ri: NewOpc = X86::ROL8r1; break; 3743 case X86::ROL16ri: NewOpc = X86::ROL16r1; break; 3744 case X86::ROL32ri: NewOpc = X86::ROL32r1; break; 3745 case X86::ROL64ri: NewOpc = X86::ROL64r1; break; 3746 case X86::SAR8ri: NewOpc = X86::SAR8r1; break; 3747 case X86::SAR16ri: NewOpc = X86::SAR16r1; break; 3748 case X86::SAR32ri: NewOpc = X86::SAR32r1; break; 3749 case X86::SAR64ri: NewOpc = X86::SAR64r1; break; 3750 case X86::SHR8ri: NewOpc = X86::SHR8r1; break; 3751 case X86::SHR16ri: NewOpc = X86::SHR16r1; break; 3752 case X86::SHR32ri: NewOpc = X86::SHR32r1; break; 3753 case X86::SHR64ri: NewOpc = X86::SHR64r1; break; 3754 case X86::SHL8ri: NewOpc = X86::SHL8r1; break; 3755 case X86::SHL16ri: NewOpc = X86::SHL16r1; break; 3756 case X86::SHL32ri: NewOpc = X86::SHL32r1; break; 3757 case X86::SHL64ri: NewOpc = X86::SHL64r1; break; 3758 } 3759 3760 MCInst TmpInst; 3761 TmpInst.setOpcode(NewOpc); 3762 TmpInst.addOperand(Inst.getOperand(0)); 3763 TmpInst.addOperand(Inst.getOperand(1)); 3764 Inst = TmpInst; 3765 return true; 3766 } 3767 case X86::RCR8mi: case X86::RCR16mi: case X86::RCR32mi: case X86::RCR64mi: 3768 case X86::RCL8mi: case X86::RCL16mi: case X86::RCL32mi: case X86::RCL64mi: 3769 case X86::ROR8mi: case X86::ROR16mi: case X86::ROR32mi: case X86::ROR64mi: 3770 case X86::ROL8mi: case X86::ROL16mi: case X86::ROL32mi: case X86::ROL64mi: 3771 case X86::SAR8mi: case X86::SAR16mi: case X86::SAR32mi: case X86::SAR64mi: 3772 case X86::SHR8mi: case X86::SHR16mi: case X86::SHR32mi: case X86::SHR64mi: 3773 case X86::SHL8mi: case X86::SHL16mi: case X86::SHL32mi: case X86::SHL64mi: { 3774 // Optimize s{hr,ar,hl} $1, <op> to "shift <op>". Similar for rotate. 3775 // FIXME: It would be great if we could just do this with an InstAlias. 3776 if (!Inst.getOperand(X86::AddrNumOperands).isImm() || 3777 Inst.getOperand(X86::AddrNumOperands).getImm() != 1) 3778 return false; 3779 3780 unsigned NewOpc; 3781 switch (Inst.getOpcode()) { 3782 default: llvm_unreachable("Invalid opcode"); 3783 case X86::RCR8mi: NewOpc = X86::RCR8m1; break; 3784 case X86::RCR16mi: NewOpc = X86::RCR16m1; break; 3785 case X86::RCR32mi: NewOpc = X86::RCR32m1; break; 3786 case X86::RCR64mi: NewOpc = X86::RCR64m1; break; 3787 case X86::RCL8mi: NewOpc = X86::RCL8m1; break; 3788 case X86::RCL16mi: NewOpc = X86::RCL16m1; break; 3789 case X86::RCL32mi: NewOpc = X86::RCL32m1; break; 3790 case X86::RCL64mi: NewOpc = X86::RCL64m1; break; 3791 case X86::ROR8mi: NewOpc = X86::ROR8m1; break; 3792 case X86::ROR16mi: NewOpc = X86::ROR16m1; break; 3793 case X86::ROR32mi: NewOpc = X86::ROR32m1; break; 3794 case X86::ROR64mi: NewOpc = X86::ROR64m1; break; 3795 case X86::ROL8mi: NewOpc = X86::ROL8m1; break; 3796 case X86::ROL16mi: NewOpc = X86::ROL16m1; break; 3797 case X86::ROL32mi: NewOpc = X86::ROL32m1; break; 3798 case X86::ROL64mi: NewOpc = X86::ROL64m1; break; 3799 case X86::SAR8mi: NewOpc = X86::SAR8m1; break; 3800 case X86::SAR16mi: NewOpc = X86::SAR16m1; break; 3801 case X86::SAR32mi: NewOpc = X86::SAR32m1; break; 3802 case X86::SAR64mi: NewOpc = X86::SAR64m1; break; 3803 case X86::SHR8mi: NewOpc = X86::SHR8m1; break; 3804 case X86::SHR16mi: NewOpc = X86::SHR16m1; break; 3805 case X86::SHR32mi: NewOpc = X86::SHR32m1; break; 3806 case X86::SHR64mi: NewOpc = X86::SHR64m1; break; 3807 case X86::SHL8mi: NewOpc = X86::SHL8m1; break; 3808 case X86::SHL16mi: NewOpc = X86::SHL16m1; break; 3809 case X86::SHL32mi: NewOpc = X86::SHL32m1; break; 3810 case X86::SHL64mi: NewOpc = X86::SHL64m1; break; 3811 } 3812 3813 MCInst TmpInst; 3814 TmpInst.setOpcode(NewOpc); 3815 for (int i = 0; i != X86::AddrNumOperands; ++i) 3816 TmpInst.addOperand(Inst.getOperand(i)); 3817 Inst = TmpInst; 3818 return true; 3819 } 3820 case X86::INT: { 3821 // Transforms "int $3" into "int3" as a size optimization. We can't write an 3822 // instalias with an immediate operand yet. 3823 if (!Inst.getOperand(0).isImm() || Inst.getOperand(0).getImm() != 3) 3824 return false; 3825 3826 MCInst TmpInst; 3827 TmpInst.setOpcode(X86::INT3); 3828 Inst = TmpInst; 3829 return true; 3830 } 3831 } 3832 } 3833 3834 bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) { 3835 const MCRegisterInfo *MRI = getContext().getRegisterInfo(); 3836 3837 switch (Inst.getOpcode()) { 3838 case X86::VGATHERDPDYrm: 3839 case X86::VGATHERDPDrm: 3840 case X86::VGATHERDPSYrm: 3841 case X86::VGATHERDPSrm: 3842 case X86::VGATHERQPDYrm: 3843 case X86::VGATHERQPDrm: 3844 case X86::VGATHERQPSYrm: 3845 case X86::VGATHERQPSrm: 3846 case X86::VPGATHERDDYrm: 3847 case X86::VPGATHERDDrm: 3848 case X86::VPGATHERDQYrm: 3849 case X86::VPGATHERDQrm: 3850 case X86::VPGATHERQDYrm: 3851 case X86::VPGATHERQDrm: 3852 case X86::VPGATHERQQYrm: 3853 case X86::VPGATHERQQrm: { 3854 unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg()); 3855 unsigned Mask = MRI->getEncodingValue(Inst.getOperand(1).getReg()); 3856 unsigned Index = 3857 MRI->getEncodingValue(Inst.getOperand(3 + X86::AddrIndexReg).getReg()); 3858 if (Dest == Mask || Dest == Index || Mask == Index) 3859 return Warning(Ops[0]->getStartLoc(), "mask, index, and destination " 3860 "registers should be distinct"); 3861 break; 3862 } 3863 case X86::VGATHERDPDZ128rm: 3864 case X86::VGATHERDPDZ256rm: 3865 case X86::VGATHERDPDZrm: 3866 case X86::VGATHERDPSZ128rm: 3867 case X86::VGATHERDPSZ256rm: 3868 case X86::VGATHERDPSZrm: 3869 case X86::VGATHERQPDZ128rm: 3870 case X86::VGATHERQPDZ256rm: 3871 case X86::VGATHERQPDZrm: 3872 case X86::VGATHERQPSZ128rm: 3873 case X86::VGATHERQPSZ256rm: 3874 case X86::VGATHERQPSZrm: 3875 case X86::VPGATHERDDZ128rm: 3876 case X86::VPGATHERDDZ256rm: 3877 case X86::VPGATHERDDZrm: 3878 case X86::VPGATHERDQZ128rm: 3879 case X86::VPGATHERDQZ256rm: 3880 case X86::VPGATHERDQZrm: 3881 case X86::VPGATHERQDZ128rm: 3882 case X86::VPGATHERQDZ256rm: 3883 case X86::VPGATHERQDZrm: 3884 case X86::VPGATHERQQZ128rm: 3885 case X86::VPGATHERQQZ256rm: 3886 case X86::VPGATHERQQZrm: { 3887 unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg()); 3888 unsigned Index = 3889 MRI->getEncodingValue(Inst.getOperand(4 + X86::AddrIndexReg).getReg()); 3890 if (Dest == Index) 3891 return Warning(Ops[0]->getStartLoc(), "index and destination registers " 3892 "should be distinct"); 3893 break; 3894 } 3895 case X86::V4FMADDPSrm: 3896 case X86::V4FMADDPSrmk: 3897 case X86::V4FMADDPSrmkz: 3898 case X86::V4FMADDSSrm: 3899 case X86::V4FMADDSSrmk: 3900 case X86::V4FMADDSSrmkz: 3901 case X86::V4FNMADDPSrm: 3902 case X86::V4FNMADDPSrmk: 3903 case X86::V4FNMADDPSrmkz: 3904 case X86::V4FNMADDSSrm: 3905 case X86::V4FNMADDSSrmk: 3906 case X86::V4FNMADDSSrmkz: 3907 case X86::VP4DPWSSDSrm: 3908 case X86::VP4DPWSSDSrmk: 3909 case X86::VP4DPWSSDSrmkz: 3910 case X86::VP4DPWSSDrm: 3911 case X86::VP4DPWSSDrmk: 3912 case X86::VP4DPWSSDrmkz: { 3913 unsigned Src2 = Inst.getOperand(Inst.getNumOperands() - 3914 X86::AddrNumOperands - 1).getReg(); 3915 unsigned Src2Enc = MRI->getEncodingValue(Src2); 3916 if (Src2Enc % 4 != 0) { 3917 StringRef RegName = X86IntelInstPrinter::getRegisterName(Src2); 3918 unsigned GroupStart = (Src2Enc / 4) * 4; 3919 unsigned GroupEnd = GroupStart + 3; 3920 return Warning(Ops[0]->getStartLoc(), 3921 "source register '" + RegName + "' implicitly denotes '" + 3922 RegName.take_front(3) + Twine(GroupStart) + "' to '" + 3923 RegName.take_front(3) + Twine(GroupEnd) + 3924 "' source group"); 3925 } 3926 break; 3927 } 3928 case X86::VFCMADDCPHZ128m: 3929 case X86::VFCMADDCPHZ256m: 3930 case X86::VFCMADDCPHZm: 3931 case X86::VFCMADDCPHZ128mb: 3932 case X86::VFCMADDCPHZ256mb: 3933 case X86::VFCMADDCPHZmb: 3934 case X86::VFCMADDCPHZ128mbk: 3935 case X86::VFCMADDCPHZ256mbk: 3936 case X86::VFCMADDCPHZmbk: 3937 case X86::VFCMADDCPHZ128mbkz: 3938 case X86::VFCMADDCPHZ256mbkz: 3939 case X86::VFCMADDCPHZmbkz: 3940 case X86::VFCMADDCPHZ128mk: 3941 case X86::VFCMADDCPHZ256mk: 3942 case X86::VFCMADDCPHZmk: 3943 case X86::VFCMADDCPHZ128mkz: 3944 case X86::VFCMADDCPHZ256mkz: 3945 case X86::VFCMADDCPHZmkz: 3946 case X86::VFCMADDCPHZ128r: 3947 case X86::VFCMADDCPHZ256r: 3948 case X86::VFCMADDCPHZr: 3949 case X86::VFCMADDCPHZ128rk: 3950 case X86::VFCMADDCPHZ256rk: 3951 case X86::VFCMADDCPHZrk: 3952 case X86::VFCMADDCPHZ128rkz: 3953 case X86::VFCMADDCPHZ256rkz: 3954 case X86::VFCMADDCPHZrkz: 3955 case X86::VFCMADDCPHZrb: 3956 case X86::VFCMADDCPHZrbk: 3957 case X86::VFCMADDCPHZrbkz: 3958 case X86::VFCMADDCSHZm: 3959 case X86::VFCMADDCSHZmk: 3960 case X86::VFCMADDCSHZmkz: 3961 case X86::VFCMADDCSHZr: 3962 case X86::VFCMADDCSHZrb: 3963 case X86::VFCMADDCSHZrbk: 3964 case X86::VFCMADDCSHZrbkz: 3965 case X86::VFCMADDCSHZrk: 3966 case X86::VFCMADDCSHZrkz: 3967 case X86::VFMADDCPHZ128m: 3968 case X86::VFMADDCPHZ256m: 3969 case X86::VFMADDCPHZm: 3970 case X86::VFMADDCPHZ128mb: 3971 case X86::VFMADDCPHZ256mb: 3972 case X86::VFMADDCPHZmb: 3973 case X86::VFMADDCPHZ128mbk: 3974 case X86::VFMADDCPHZ256mbk: 3975 case X86::VFMADDCPHZmbk: 3976 case X86::VFMADDCPHZ128mbkz: 3977 case X86::VFMADDCPHZ256mbkz: 3978 case X86::VFMADDCPHZmbkz: 3979 case X86::VFMADDCPHZ128mk: 3980 case X86::VFMADDCPHZ256mk: 3981 case X86::VFMADDCPHZmk: 3982 case X86::VFMADDCPHZ128mkz: 3983 case X86::VFMADDCPHZ256mkz: 3984 case X86::VFMADDCPHZmkz: 3985 case X86::VFMADDCPHZ128r: 3986 case X86::VFMADDCPHZ256r: 3987 case X86::VFMADDCPHZr: 3988 case X86::VFMADDCPHZ128rk: 3989 case X86::VFMADDCPHZ256rk: 3990 case X86::VFMADDCPHZrk: 3991 case X86::VFMADDCPHZ128rkz: 3992 case X86::VFMADDCPHZ256rkz: 3993 case X86::VFMADDCPHZrkz: 3994 case X86::VFMADDCPHZrb: 3995 case X86::VFMADDCPHZrbk: 3996 case X86::VFMADDCPHZrbkz: 3997 case X86::VFMADDCSHZm: 3998 case X86::VFMADDCSHZmk: 3999 case X86::VFMADDCSHZmkz: 4000 case X86::VFMADDCSHZr: 4001 case X86::VFMADDCSHZrb: 4002 case X86::VFMADDCSHZrbk: 4003 case X86::VFMADDCSHZrbkz: 4004 case X86::VFMADDCSHZrk: 4005 case X86::VFMADDCSHZrkz: { 4006 unsigned Dest = Inst.getOperand(0).getReg(); 4007 for (unsigned i = 2; i < Inst.getNumOperands(); i++) 4008 if (Inst.getOperand(i).isReg() && Dest == Inst.getOperand(i).getReg()) 4009 return Warning(Ops[0]->getStartLoc(), "Destination register should be " 4010 "distinct from source registers"); 4011 break; 4012 } 4013 case X86::VFCMULCPHZ128rm: 4014 case X86::VFCMULCPHZ256rm: 4015 case X86::VFCMULCPHZrm: 4016 case X86::VFCMULCPHZ128rmb: 4017 case X86::VFCMULCPHZ256rmb: 4018 case X86::VFCMULCPHZrmb: 4019 case X86::VFCMULCPHZ128rmbk: 4020 case X86::VFCMULCPHZ256rmbk: 4021 case X86::VFCMULCPHZrmbk: 4022 case X86::VFCMULCPHZ128rmbkz: 4023 case X86::VFCMULCPHZ256rmbkz: 4024 case X86::VFCMULCPHZrmbkz: 4025 case X86::VFCMULCPHZ128rmk: 4026 case X86::VFCMULCPHZ256rmk: 4027 case X86::VFCMULCPHZrmk: 4028 case X86::VFCMULCPHZ128rmkz: 4029 case X86::VFCMULCPHZ256rmkz: 4030 case X86::VFCMULCPHZrmkz: 4031 case X86::VFCMULCPHZ128rr: 4032 case X86::VFCMULCPHZ256rr: 4033 case X86::VFCMULCPHZrr: 4034 case X86::VFCMULCPHZ128rrk: 4035 case X86::VFCMULCPHZ256rrk: 4036 case X86::VFCMULCPHZrrk: 4037 case X86::VFCMULCPHZ128rrkz: 4038 case X86::VFCMULCPHZ256rrkz: 4039 case X86::VFCMULCPHZrrkz: 4040 case X86::VFCMULCPHZrrb: 4041 case X86::VFCMULCPHZrrbk: 4042 case X86::VFCMULCPHZrrbkz: 4043 case X86::VFCMULCSHZrm: 4044 case X86::VFCMULCSHZrmk: 4045 case X86::VFCMULCSHZrmkz: 4046 case X86::VFCMULCSHZrr: 4047 case X86::VFCMULCSHZrrb: 4048 case X86::VFCMULCSHZrrbk: 4049 case X86::VFCMULCSHZrrbkz: 4050 case X86::VFCMULCSHZrrk: 4051 case X86::VFCMULCSHZrrkz: 4052 case X86::VFMULCPHZ128rm: 4053 case X86::VFMULCPHZ256rm: 4054 case X86::VFMULCPHZrm: 4055 case X86::VFMULCPHZ128rmb: 4056 case X86::VFMULCPHZ256rmb: 4057 case X86::VFMULCPHZrmb: 4058 case X86::VFMULCPHZ128rmbk: 4059 case X86::VFMULCPHZ256rmbk: 4060 case X86::VFMULCPHZrmbk: 4061 case X86::VFMULCPHZ128rmbkz: 4062 case X86::VFMULCPHZ256rmbkz: 4063 case X86::VFMULCPHZrmbkz: 4064 case X86::VFMULCPHZ128rmk: 4065 case X86::VFMULCPHZ256rmk: 4066 case X86::VFMULCPHZrmk: 4067 case X86::VFMULCPHZ128rmkz: 4068 case X86::VFMULCPHZ256rmkz: 4069 case X86::VFMULCPHZrmkz: 4070 case X86::VFMULCPHZ128rr: 4071 case X86::VFMULCPHZ256rr: 4072 case X86::VFMULCPHZrr: 4073 case X86::VFMULCPHZ128rrk: 4074 case X86::VFMULCPHZ256rrk: 4075 case X86::VFMULCPHZrrk: 4076 case X86::VFMULCPHZ128rrkz: 4077 case X86::VFMULCPHZ256rrkz: 4078 case X86::VFMULCPHZrrkz: 4079 case X86::VFMULCPHZrrb: 4080 case X86::VFMULCPHZrrbk: 4081 case X86::VFMULCPHZrrbkz: 4082 case X86::VFMULCSHZrm: 4083 case X86::VFMULCSHZrmk: 4084 case X86::VFMULCSHZrmkz: 4085 case X86::VFMULCSHZrr: 4086 case X86::VFMULCSHZrrb: 4087 case X86::VFMULCSHZrrbk: 4088 case X86::VFMULCSHZrrbkz: 4089 case X86::VFMULCSHZrrk: 4090 case X86::VFMULCSHZrrkz: { 4091 unsigned Dest = Inst.getOperand(0).getReg(); 4092 for (unsigned i = 1; i < Inst.getNumOperands(); i++) 4093 if (Inst.getOperand(i).isReg() && Dest == Inst.getOperand(i).getReg()) 4094 return Warning(Ops[0]->getStartLoc(), "Destination register should be " 4095 "distinct from source registers"); 4096 break; 4097 } 4098 } 4099 4100 const MCInstrDesc &MCID = MII.get(Inst.getOpcode()); 4101 // Check that we aren't mixing AH/BH/CH/DH with REX prefix. We only need to 4102 // check this with the legacy encoding, VEX/EVEX/XOP don't use REX. 4103 if ((MCID.TSFlags & X86II::EncodingMask) == 0) { 4104 MCPhysReg HReg = X86::NoRegister; 4105 bool UsesRex = MCID.TSFlags & X86II::REX_W; 4106 unsigned NumOps = Inst.getNumOperands(); 4107 for (unsigned i = 0; i != NumOps; ++i) { 4108 const MCOperand &MO = Inst.getOperand(i); 4109 if (!MO.isReg()) 4110 continue; 4111 unsigned Reg = MO.getReg(); 4112 if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH) 4113 HReg = Reg; 4114 if (X86II::isX86_64NonExtLowByteReg(Reg) || 4115 X86II::isX86_64ExtendedReg(Reg)) 4116 UsesRex = true; 4117 } 4118 4119 if (UsesRex && HReg != X86::NoRegister) { 4120 StringRef RegName = X86IntelInstPrinter::getRegisterName(HReg); 4121 return Error(Ops[0]->getStartLoc(), 4122 "can't encode '" + RegName + "' in an instruction requiring " 4123 "REX prefix"); 4124 } 4125 } 4126 4127 return false; 4128 } 4129 4130 static const char *getSubtargetFeatureName(uint64_t Val); 4131 4132 void X86AsmParser::emitWarningForSpecialLVIInstruction(SMLoc Loc) { 4133 Warning(Loc, "Instruction may be vulnerable to LVI and " 4134 "requires manual mitigation"); 4135 Note(SMLoc(), "See https://software.intel.com/" 4136 "security-software-guidance/insights/" 4137 "deep-dive-load-value-injection#specialinstructions" 4138 " for more information"); 4139 } 4140 4141 /// RET instructions and also instructions that indirect calls/jumps from memory 4142 /// combine a load and a branch within a single instruction. To mitigate these 4143 /// instructions against LVI, they must be decomposed into separate load and 4144 /// branch instructions, with an LFENCE in between. For more details, see: 4145 /// - X86LoadValueInjectionRetHardening.cpp 4146 /// - X86LoadValueInjectionIndirectThunks.cpp 4147 /// - https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection 4148 /// 4149 /// Returns `true` if a mitigation was applied or warning was emitted. 4150 void X86AsmParser::applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out) { 4151 // Information on control-flow instructions that require manual mitigation can 4152 // be found here: 4153 // https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection#specialinstructions 4154 switch (Inst.getOpcode()) { 4155 case X86::RET16: 4156 case X86::RET32: 4157 case X86::RET64: 4158 case X86::RETI16: 4159 case X86::RETI32: 4160 case X86::RETI64: { 4161 MCInst ShlInst, FenceInst; 4162 bool Parse32 = is32BitMode() || Code16GCC; 4163 unsigned Basereg = 4164 is64BitMode() ? X86::RSP : (Parse32 ? X86::ESP : X86::SP); 4165 const MCExpr *Disp = MCConstantExpr::create(0, getContext()); 4166 auto ShlMemOp = X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp, 4167 /*BaseReg=*/Basereg, /*IndexReg=*/0, 4168 /*Scale=*/1, SMLoc{}, SMLoc{}, 0); 4169 ShlInst.setOpcode(X86::SHL64mi); 4170 ShlMemOp->addMemOperands(ShlInst, 5); 4171 ShlInst.addOperand(MCOperand::createImm(0)); 4172 FenceInst.setOpcode(X86::LFENCE); 4173 Out.emitInstruction(ShlInst, getSTI()); 4174 Out.emitInstruction(FenceInst, getSTI()); 4175 return; 4176 } 4177 case X86::JMP16m: 4178 case X86::JMP32m: 4179 case X86::JMP64m: 4180 case X86::CALL16m: 4181 case X86::CALL32m: 4182 case X86::CALL64m: 4183 emitWarningForSpecialLVIInstruction(Inst.getLoc()); 4184 return; 4185 } 4186 } 4187 4188 /// To mitigate LVI, every instruction that performs a load can be followed by 4189 /// an LFENCE instruction to squash any potential mis-speculation. There are 4190 /// some instructions that require additional considerations, and may requre 4191 /// manual mitigation. For more details, see: 4192 /// https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection 4193 /// 4194 /// Returns `true` if a mitigation was applied or warning was emitted. 4195 void X86AsmParser::applyLVILoadHardeningMitigation(MCInst &Inst, 4196 MCStreamer &Out) { 4197 auto Opcode = Inst.getOpcode(); 4198 auto Flags = Inst.getFlags(); 4199 if ((Flags & X86::IP_HAS_REPEAT) || (Flags & X86::IP_HAS_REPEAT_NE)) { 4200 // Information on REP string instructions that require manual mitigation can 4201 // be found here: 4202 // https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection#specialinstructions 4203 switch (Opcode) { 4204 case X86::CMPSB: 4205 case X86::CMPSW: 4206 case X86::CMPSL: 4207 case X86::CMPSQ: 4208 case X86::SCASB: 4209 case X86::SCASW: 4210 case X86::SCASL: 4211 case X86::SCASQ: 4212 emitWarningForSpecialLVIInstruction(Inst.getLoc()); 4213 return; 4214 } 4215 } else if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) { 4216 // If a REP instruction is found on its own line, it may or may not be 4217 // followed by a vulnerable instruction. Emit a warning just in case. 4218 emitWarningForSpecialLVIInstruction(Inst.getLoc()); 4219 return; 4220 } 4221 4222 const MCInstrDesc &MCID = MII.get(Inst.getOpcode()); 4223 4224 // Can't mitigate after terminators or calls. A control flow change may have 4225 // already occurred. 4226 if (MCID.isTerminator() || MCID.isCall()) 4227 return; 4228 4229 // LFENCE has the mayLoad property, don't double fence. 4230 if (MCID.mayLoad() && Inst.getOpcode() != X86::LFENCE) { 4231 MCInst FenceInst; 4232 FenceInst.setOpcode(X86::LFENCE); 4233 Out.emitInstruction(FenceInst, getSTI()); 4234 } 4235 } 4236 4237 void X86AsmParser::emitInstruction(MCInst &Inst, OperandVector &Operands, 4238 MCStreamer &Out) { 4239 if (LVIInlineAsmHardening && 4240 getSTI().getFeatureBits()[X86::FeatureLVIControlFlowIntegrity]) 4241 applyLVICFIMitigation(Inst, Out); 4242 4243 Out.emitInstruction(Inst, getSTI()); 4244 4245 if (LVIInlineAsmHardening && 4246 getSTI().getFeatureBits()[X86::FeatureLVILoadHardening]) 4247 applyLVILoadHardeningMitigation(Inst, Out); 4248 } 4249 4250 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 4251 OperandVector &Operands, 4252 MCStreamer &Out, uint64_t &ErrorInfo, 4253 bool MatchingInlineAsm) { 4254 if (isParsingIntelSyntax()) 4255 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo, 4256 MatchingInlineAsm); 4257 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo, 4258 MatchingInlineAsm); 4259 } 4260 4261 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, 4262 OperandVector &Operands, MCStreamer &Out, 4263 bool MatchingInlineAsm) { 4264 // FIXME: This should be replaced with a real .td file alias mechanism. 4265 // Also, MatchInstructionImpl should actually *do* the EmitInstruction 4266 // call. 4267 const char *Repl = StringSwitch<const char *>(Op.getToken()) 4268 .Case("finit", "fninit") 4269 .Case("fsave", "fnsave") 4270 .Case("fstcw", "fnstcw") 4271 .Case("fstcww", "fnstcw") 4272 .Case("fstenv", "fnstenv") 4273 .Case("fstsw", "fnstsw") 4274 .Case("fstsww", "fnstsw") 4275 .Case("fclex", "fnclex") 4276 .Default(nullptr); 4277 if (Repl) { 4278 MCInst Inst; 4279 Inst.setOpcode(X86::WAIT); 4280 Inst.setLoc(IDLoc); 4281 if (!MatchingInlineAsm) 4282 emitInstruction(Inst, Operands, Out); 4283 Operands[0] = X86Operand::CreateToken(Repl, IDLoc); 4284 } 4285 } 4286 4287 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, 4288 const FeatureBitset &MissingFeatures, 4289 bool MatchingInlineAsm) { 4290 assert(MissingFeatures.any() && "Unknown missing feature!"); 4291 SmallString<126> Msg; 4292 raw_svector_ostream OS(Msg); 4293 OS << "instruction requires:"; 4294 for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) { 4295 if (MissingFeatures[i]) 4296 OS << ' ' << getSubtargetFeatureName(i); 4297 } 4298 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm); 4299 } 4300 4301 static unsigned getPrefixes(OperandVector &Operands) { 4302 unsigned Result = 0; 4303 X86Operand &Prefix = static_cast<X86Operand &>(*Operands.back()); 4304 if (Prefix.isPrefix()) { 4305 Result = Prefix.getPrefix(); 4306 Operands.pop_back(); 4307 } 4308 return Result; 4309 } 4310 4311 unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) { 4312 unsigned Opc = Inst.getOpcode(); 4313 const MCInstrDesc &MCID = MII.get(Opc); 4314 4315 if (ForcedVEXEncoding == VEXEncoding_EVEX && 4316 (MCID.TSFlags & X86II::EncodingMask) != X86II::EVEX) 4317 return Match_Unsupported; 4318 4319 if ((ForcedVEXEncoding == VEXEncoding_VEX || 4320 ForcedVEXEncoding == VEXEncoding_VEX2 || 4321 ForcedVEXEncoding == VEXEncoding_VEX3) && 4322 (MCID.TSFlags & X86II::EncodingMask) != X86II::VEX) 4323 return Match_Unsupported; 4324 4325 // These instructions are only available with {vex}, {vex2} or {vex3} prefix 4326 if (MCID.TSFlags & X86II::ExplicitVEXPrefix && 4327 (ForcedVEXEncoding != VEXEncoding_VEX && 4328 ForcedVEXEncoding != VEXEncoding_VEX2 && 4329 ForcedVEXEncoding != VEXEncoding_VEX3)) 4330 return Match_Unsupported; 4331 4332 return Match_Success; 4333 } 4334 4335 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode, 4336 OperandVector &Operands, 4337 MCStreamer &Out, 4338 uint64_t &ErrorInfo, 4339 bool MatchingInlineAsm) { 4340 assert(!Operands.empty() && "Unexpect empty operand list!"); 4341 assert((*Operands[0]).isToken() && "Leading operand should always be a mnemonic!"); 4342 SMRange EmptyRange = None; 4343 4344 // First, handle aliases that expand to multiple instructions. 4345 MatchFPUWaitAlias(IDLoc, static_cast<X86Operand &>(*Operands[0]), Operands, 4346 Out, MatchingInlineAsm); 4347 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]); 4348 unsigned Prefixes = getPrefixes(Operands); 4349 4350 MCInst Inst; 4351 4352 // If VEX/EVEX encoding is forced, we need to pass the USE_* flag to the 4353 // encoder and printer. 4354 if (ForcedVEXEncoding == VEXEncoding_VEX) 4355 Prefixes |= X86::IP_USE_VEX; 4356 else if (ForcedVEXEncoding == VEXEncoding_VEX2) 4357 Prefixes |= X86::IP_USE_VEX2; 4358 else if (ForcedVEXEncoding == VEXEncoding_VEX3) 4359 Prefixes |= X86::IP_USE_VEX3; 4360 else if (ForcedVEXEncoding == VEXEncoding_EVEX) 4361 Prefixes |= X86::IP_USE_EVEX; 4362 4363 // Set encoded flags for {disp8} and {disp32}. 4364 if (ForcedDispEncoding == DispEncoding_Disp8) 4365 Prefixes |= X86::IP_USE_DISP8; 4366 else if (ForcedDispEncoding == DispEncoding_Disp32) 4367 Prefixes |= X86::IP_USE_DISP32; 4368 4369 if (Prefixes) 4370 Inst.setFlags(Prefixes); 4371 4372 // In 16-bit mode, if data32 is specified, temporarily switch to 32-bit mode 4373 // when matching the instruction. 4374 if (ForcedDataPrefix == X86::Is32Bit) 4375 SwitchMode(X86::Is32Bit); 4376 // First, try a direct match. 4377 FeatureBitset MissingFeatures; 4378 unsigned OriginalError = MatchInstruction(Operands, Inst, ErrorInfo, 4379 MissingFeatures, MatchingInlineAsm, 4380 isParsingIntelSyntax()); 4381 if (ForcedDataPrefix == X86::Is32Bit) { 4382 SwitchMode(X86::Is16Bit); 4383 ForcedDataPrefix = 0; 4384 } 4385 switch (OriginalError) { 4386 default: llvm_unreachable("Unexpected match result!"); 4387 case Match_Success: 4388 if (!MatchingInlineAsm && validateInstruction(Inst, Operands)) 4389 return true; 4390 // Some instructions need post-processing to, for example, tweak which 4391 // encoding is selected. Loop on it while changes happen so the 4392 // individual transformations can chain off each other. 4393 if (!MatchingInlineAsm) 4394 while (processInstruction(Inst, Operands)) 4395 ; 4396 4397 Inst.setLoc(IDLoc); 4398 if (!MatchingInlineAsm) 4399 emitInstruction(Inst, Operands, Out); 4400 Opcode = Inst.getOpcode(); 4401 return false; 4402 case Match_InvalidImmUnsignedi4: { 4403 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc(); 4404 if (ErrorLoc == SMLoc()) 4405 ErrorLoc = IDLoc; 4406 return Error(ErrorLoc, "immediate must be an integer in range [0, 15]", 4407 EmptyRange, MatchingInlineAsm); 4408 } 4409 case Match_MissingFeature: 4410 return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm); 4411 case Match_InvalidOperand: 4412 case Match_MnemonicFail: 4413 case Match_Unsupported: 4414 break; 4415 } 4416 if (Op.getToken().empty()) { 4417 Error(IDLoc, "instruction must have size higher than 0", EmptyRange, 4418 MatchingInlineAsm); 4419 return true; 4420 } 4421 4422 // FIXME: Ideally, we would only attempt suffix matches for things which are 4423 // valid prefixes, and we could just infer the right unambiguous 4424 // type. However, that requires substantially more matcher support than the 4425 // following hack. 4426 4427 // Change the operand to point to a temporary token. 4428 StringRef Base = Op.getToken(); 4429 SmallString<16> Tmp; 4430 Tmp += Base; 4431 Tmp += ' '; 4432 Op.setTokenValue(Tmp); 4433 4434 // If this instruction starts with an 'f', then it is a floating point stack 4435 // instruction. These come in up to three forms for 32-bit, 64-bit, and 4436 // 80-bit floating point, which use the suffixes s,l,t respectively. 4437 // 4438 // Otherwise, we assume that this may be an integer instruction, which comes 4439 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively. 4440 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0"; 4441 // MemSize corresponding to Suffixes. { 8, 16, 32, 64 } { 32, 64, 80, 0 } 4442 const char *MemSize = Base[0] != 'f' ? "\x08\x10\x20\x40" : "\x20\x40\x50\0"; 4443 4444 // Check for the various suffix matches. 4445 uint64_t ErrorInfoIgnore; 4446 FeatureBitset ErrorInfoMissingFeatures; // Init suppresses compiler warnings. 4447 unsigned Match[4]; 4448 4449 // Some instruction like VPMULDQ is NOT the variant of VPMULD but a new one. 4450 // So we should make sure the suffix matcher only works for memory variant 4451 // that has the same size with the suffix. 4452 // FIXME: This flag is a workaround for legacy instructions that didn't 4453 // declare non suffix variant assembly. 4454 bool HasVectorReg = false; 4455 X86Operand *MemOp = nullptr; 4456 for (const auto &Op : Operands) { 4457 X86Operand *X86Op = static_cast<X86Operand *>(Op.get()); 4458 if (X86Op->isVectorReg()) 4459 HasVectorReg = true; 4460 else if (X86Op->isMem()) { 4461 MemOp = X86Op; 4462 assert(MemOp->Mem.Size == 0 && "Memory size always 0 under ATT syntax"); 4463 // Have we found an unqualified memory operand, 4464 // break. IA allows only one memory operand. 4465 break; 4466 } 4467 } 4468 4469 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) { 4470 Tmp.back() = Suffixes[I]; 4471 if (MemOp && HasVectorReg) 4472 MemOp->Mem.Size = MemSize[I]; 4473 Match[I] = Match_MnemonicFail; 4474 if (MemOp || !HasVectorReg) { 4475 Match[I] = 4476 MatchInstruction(Operands, Inst, ErrorInfoIgnore, MissingFeatures, 4477 MatchingInlineAsm, isParsingIntelSyntax()); 4478 // If this returned as a missing feature failure, remember that. 4479 if (Match[I] == Match_MissingFeature) 4480 ErrorInfoMissingFeatures = MissingFeatures; 4481 } 4482 } 4483 4484 // Restore the old token. 4485 Op.setTokenValue(Base); 4486 4487 // If exactly one matched, then we treat that as a successful match (and the 4488 // instruction will already have been filled in correctly, since the failing 4489 // matches won't have modified it). 4490 unsigned NumSuccessfulMatches = llvm::count(Match, Match_Success); 4491 if (NumSuccessfulMatches == 1) { 4492 if (!MatchingInlineAsm && validateInstruction(Inst, Operands)) 4493 return true; 4494 // Some instructions need post-processing to, for example, tweak which 4495 // encoding is selected. Loop on it while changes happen so the 4496 // individual transformations can chain off each other. 4497 if (!MatchingInlineAsm) 4498 while (processInstruction(Inst, Operands)) 4499 ; 4500 4501 Inst.setLoc(IDLoc); 4502 if (!MatchingInlineAsm) 4503 emitInstruction(Inst, Operands, Out); 4504 Opcode = Inst.getOpcode(); 4505 return false; 4506 } 4507 4508 // Otherwise, the match failed, try to produce a decent error message. 4509 4510 // If we had multiple suffix matches, then identify this as an ambiguous 4511 // match. 4512 if (NumSuccessfulMatches > 1) { 4513 char MatchChars[4]; 4514 unsigned NumMatches = 0; 4515 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) 4516 if (Match[I] == Match_Success) 4517 MatchChars[NumMatches++] = Suffixes[I]; 4518 4519 SmallString<126> Msg; 4520 raw_svector_ostream OS(Msg); 4521 OS << "ambiguous instructions require an explicit suffix (could be "; 4522 for (unsigned i = 0; i != NumMatches; ++i) { 4523 if (i != 0) 4524 OS << ", "; 4525 if (i + 1 == NumMatches) 4526 OS << "or "; 4527 OS << "'" << Base << MatchChars[i] << "'"; 4528 } 4529 OS << ")"; 4530 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm); 4531 return true; 4532 } 4533 4534 // Okay, we know that none of the variants matched successfully. 4535 4536 // If all of the instructions reported an invalid mnemonic, then the original 4537 // mnemonic was invalid. 4538 if (llvm::count(Match, Match_MnemonicFail) == 4) { 4539 if (OriginalError == Match_MnemonicFail) 4540 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'", 4541 Op.getLocRange(), MatchingInlineAsm); 4542 4543 if (OriginalError == Match_Unsupported) 4544 return Error(IDLoc, "unsupported instruction", EmptyRange, 4545 MatchingInlineAsm); 4546 4547 assert(OriginalError == Match_InvalidOperand && "Unexpected error"); 4548 // Recover location info for the operand if we know which was the problem. 4549 if (ErrorInfo != ~0ULL) { 4550 if (ErrorInfo >= Operands.size()) 4551 return Error(IDLoc, "too few operands for instruction", EmptyRange, 4552 MatchingInlineAsm); 4553 4554 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo]; 4555 if (Operand.getStartLoc().isValid()) { 4556 SMRange OperandRange = Operand.getLocRange(); 4557 return Error(Operand.getStartLoc(), "invalid operand for instruction", 4558 OperandRange, MatchingInlineAsm); 4559 } 4560 } 4561 4562 return Error(IDLoc, "invalid operand for instruction", EmptyRange, 4563 MatchingInlineAsm); 4564 } 4565 4566 // If one instruction matched as unsupported, report this as unsupported. 4567 if (llvm::count(Match, Match_Unsupported) == 1) { 4568 return Error(IDLoc, "unsupported instruction", EmptyRange, 4569 MatchingInlineAsm); 4570 } 4571 4572 // If one instruction matched with a missing feature, report this as a 4573 // missing feature. 4574 if (llvm::count(Match, Match_MissingFeature) == 1) { 4575 ErrorInfo = Match_MissingFeature; 4576 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures, 4577 MatchingInlineAsm); 4578 } 4579 4580 // If one instruction matched with an invalid operand, report this as an 4581 // operand failure. 4582 if (llvm::count(Match, Match_InvalidOperand) == 1) { 4583 return Error(IDLoc, "invalid operand for instruction", EmptyRange, 4584 MatchingInlineAsm); 4585 } 4586 4587 // If all of these were an outright failure, report it in a useless way. 4588 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix", 4589 EmptyRange, MatchingInlineAsm); 4590 return true; 4591 } 4592 4593 bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode, 4594 OperandVector &Operands, 4595 MCStreamer &Out, 4596 uint64_t &ErrorInfo, 4597 bool MatchingInlineAsm) { 4598 assert(!Operands.empty() && "Unexpect empty operand list!"); 4599 assert((*Operands[0]).isToken() && "Leading operand should always be a mnemonic!"); 4600 StringRef Mnemonic = (static_cast<X86Operand &>(*Operands[0])).getToken(); 4601 SMRange EmptyRange = None; 4602 StringRef Base = (static_cast<X86Operand &>(*Operands[0])).getToken(); 4603 unsigned Prefixes = getPrefixes(Operands); 4604 4605 // First, handle aliases that expand to multiple instructions. 4606 MatchFPUWaitAlias(IDLoc, static_cast<X86Operand &>(*Operands[0]), Operands, Out, MatchingInlineAsm); 4607 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]); 4608 4609 MCInst Inst; 4610 4611 // If VEX/EVEX encoding is forced, we need to pass the USE_* flag to the 4612 // encoder and printer. 4613 if (ForcedVEXEncoding == VEXEncoding_VEX) 4614 Prefixes |= X86::IP_USE_VEX; 4615 else if (ForcedVEXEncoding == VEXEncoding_VEX2) 4616 Prefixes |= X86::IP_USE_VEX2; 4617 else if (ForcedVEXEncoding == VEXEncoding_VEX3) 4618 Prefixes |= X86::IP_USE_VEX3; 4619 else if (ForcedVEXEncoding == VEXEncoding_EVEX) 4620 Prefixes |= X86::IP_USE_EVEX; 4621 4622 // Set encoded flags for {disp8} and {disp32}. 4623 if (ForcedDispEncoding == DispEncoding_Disp8) 4624 Prefixes |= X86::IP_USE_DISP8; 4625 else if (ForcedDispEncoding == DispEncoding_Disp32) 4626 Prefixes |= X86::IP_USE_DISP32; 4627 4628 if (Prefixes) 4629 Inst.setFlags(Prefixes); 4630 4631 // Find one unsized memory operand, if present. 4632 X86Operand *UnsizedMemOp = nullptr; 4633 for (const auto &Op : Operands) { 4634 X86Operand *X86Op = static_cast<X86Operand *>(Op.get()); 4635 if (X86Op->isMemUnsized()) { 4636 UnsizedMemOp = X86Op; 4637 // Have we found an unqualified memory operand, 4638 // break. IA allows only one memory operand. 4639 break; 4640 } 4641 } 4642 4643 // Allow some instructions to have implicitly pointer-sized operands. This is 4644 // compatible with gas. 4645 if (UnsizedMemOp) { 4646 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"}; 4647 for (const char *Instr : PtrSizedInstrs) { 4648 if (Mnemonic == Instr) { 4649 UnsizedMemOp->Mem.Size = getPointerWidth(); 4650 break; 4651 } 4652 } 4653 } 4654 4655 SmallVector<unsigned, 8> Match; 4656 FeatureBitset ErrorInfoMissingFeatures; 4657 FeatureBitset MissingFeatures; 4658 4659 // If unsized push has immediate operand we should default the default pointer 4660 // size for the size. 4661 if (Mnemonic == "push" && Operands.size() == 2) { 4662 auto *X86Op = static_cast<X86Operand *>(Operands[1].get()); 4663 if (X86Op->isImm()) { 4664 // If it's not a constant fall through and let remainder take care of it. 4665 const auto *CE = dyn_cast<MCConstantExpr>(X86Op->getImm()); 4666 unsigned Size = getPointerWidth(); 4667 if (CE && 4668 (isIntN(Size, CE->getValue()) || isUIntN(Size, CE->getValue()))) { 4669 SmallString<16> Tmp; 4670 Tmp += Base; 4671 Tmp += (is64BitMode()) 4672 ? "q" 4673 : (is32BitMode()) ? "l" : (is16BitMode()) ? "w" : " "; 4674 Op.setTokenValue(Tmp); 4675 // Do match in ATT mode to allow explicit suffix usage. 4676 Match.push_back(MatchInstruction(Operands, Inst, ErrorInfo, 4677 MissingFeatures, MatchingInlineAsm, 4678 false /*isParsingIntelSyntax()*/)); 4679 Op.setTokenValue(Base); 4680 } 4681 } 4682 } 4683 4684 // If an unsized memory operand is present, try to match with each memory 4685 // operand size. In Intel assembly, the size is not part of the instruction 4686 // mnemonic. 4687 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) { 4688 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512}; 4689 for (unsigned Size : MopSizes) { 4690 UnsizedMemOp->Mem.Size = Size; 4691 uint64_t ErrorInfoIgnore; 4692 unsigned LastOpcode = Inst.getOpcode(); 4693 unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore, 4694 MissingFeatures, MatchingInlineAsm, 4695 isParsingIntelSyntax()); 4696 if (Match.empty() || LastOpcode != Inst.getOpcode()) 4697 Match.push_back(M); 4698 4699 // If this returned as a missing feature failure, remember that. 4700 if (Match.back() == Match_MissingFeature) 4701 ErrorInfoMissingFeatures = MissingFeatures; 4702 } 4703 4704 // Restore the size of the unsized memory operand if we modified it. 4705 UnsizedMemOp->Mem.Size = 0; 4706 } 4707 4708 // If we haven't matched anything yet, this is not a basic integer or FPU 4709 // operation. There shouldn't be any ambiguity in our mnemonic table, so try 4710 // matching with the unsized operand. 4711 if (Match.empty()) { 4712 Match.push_back(MatchInstruction( 4713 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm, 4714 isParsingIntelSyntax())); 4715 // If this returned as a missing feature failure, remember that. 4716 if (Match.back() == Match_MissingFeature) 4717 ErrorInfoMissingFeatures = MissingFeatures; 4718 } 4719 4720 // Restore the size of the unsized memory operand if we modified it. 4721 if (UnsizedMemOp) 4722 UnsizedMemOp->Mem.Size = 0; 4723 4724 // If it's a bad mnemonic, all results will be the same. 4725 if (Match.back() == Match_MnemonicFail) { 4726 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'", 4727 Op.getLocRange(), MatchingInlineAsm); 4728 } 4729 4730 unsigned NumSuccessfulMatches = llvm::count(Match, Match_Success); 4731 4732 // If matching was ambiguous and we had size information from the frontend, 4733 // try again with that. This handles cases like "movxz eax, m8/m16". 4734 if (UnsizedMemOp && NumSuccessfulMatches > 1 && 4735 UnsizedMemOp->getMemFrontendSize()) { 4736 UnsizedMemOp->Mem.Size = UnsizedMemOp->getMemFrontendSize(); 4737 unsigned M = MatchInstruction( 4738 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm, 4739 isParsingIntelSyntax()); 4740 if (M == Match_Success) 4741 NumSuccessfulMatches = 1; 4742 4743 // Add a rewrite that encodes the size information we used from the 4744 // frontend. 4745 InstInfo->AsmRewrites->emplace_back( 4746 AOK_SizeDirective, UnsizedMemOp->getStartLoc(), 4747 /*Len=*/0, UnsizedMemOp->getMemFrontendSize()); 4748 } 4749 4750 // If exactly one matched, then we treat that as a successful match (and the 4751 // instruction will already have been filled in correctly, since the failing 4752 // matches won't have modified it). 4753 if (NumSuccessfulMatches == 1) { 4754 if (!MatchingInlineAsm && validateInstruction(Inst, Operands)) 4755 return true; 4756 // Some instructions need post-processing to, for example, tweak which 4757 // encoding is selected. Loop on it while changes happen so the individual 4758 // transformations can chain off each other. 4759 if (!MatchingInlineAsm) 4760 while (processInstruction(Inst, Operands)) 4761 ; 4762 Inst.setLoc(IDLoc); 4763 if (!MatchingInlineAsm) 4764 emitInstruction(Inst, Operands, Out); 4765 Opcode = Inst.getOpcode(); 4766 return false; 4767 } else if (NumSuccessfulMatches > 1) { 4768 assert(UnsizedMemOp && 4769 "multiple matches only possible with unsized memory operands"); 4770 return Error(UnsizedMemOp->getStartLoc(), 4771 "ambiguous operand size for instruction '" + Mnemonic + "\'", 4772 UnsizedMemOp->getLocRange()); 4773 } 4774 4775 // If one instruction matched as unsupported, report this as unsupported. 4776 if (llvm::count(Match, Match_Unsupported) == 1) { 4777 return Error(IDLoc, "unsupported instruction", EmptyRange, 4778 MatchingInlineAsm); 4779 } 4780 4781 // If one instruction matched with a missing feature, report this as a 4782 // missing feature. 4783 if (llvm::count(Match, Match_MissingFeature) == 1) { 4784 ErrorInfo = Match_MissingFeature; 4785 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures, 4786 MatchingInlineAsm); 4787 } 4788 4789 // If one instruction matched with an invalid operand, report this as an 4790 // operand failure. 4791 if (llvm::count(Match, Match_InvalidOperand) == 1) { 4792 return Error(IDLoc, "invalid operand for instruction", EmptyRange, 4793 MatchingInlineAsm); 4794 } 4795 4796 if (llvm::count(Match, Match_InvalidImmUnsignedi4) == 1) { 4797 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc(); 4798 if (ErrorLoc == SMLoc()) 4799 ErrorLoc = IDLoc; 4800 return Error(ErrorLoc, "immediate must be an integer in range [0, 15]", 4801 EmptyRange, MatchingInlineAsm); 4802 } 4803 4804 // If all of these were an outright failure, report it in a useless way. 4805 return Error(IDLoc, "unknown instruction mnemonic", EmptyRange, 4806 MatchingInlineAsm); 4807 } 4808 4809 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) { 4810 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo); 4811 } 4812 4813 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) { 4814 MCAsmParser &Parser = getParser(); 4815 StringRef IDVal = DirectiveID.getIdentifier(); 4816 if (IDVal.startswith(".arch")) 4817 return parseDirectiveArch(); 4818 if (IDVal.startswith(".code")) 4819 return ParseDirectiveCode(IDVal, DirectiveID.getLoc()); 4820 else if (IDVal.startswith(".att_syntax")) { 4821 if (getLexer().isNot(AsmToken::EndOfStatement)) { 4822 if (Parser.getTok().getString() == "prefix") 4823 Parser.Lex(); 4824 else if (Parser.getTok().getString() == "noprefix") 4825 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not " 4826 "supported: registers must have a " 4827 "'%' prefix in .att_syntax"); 4828 } 4829 getParser().setAssemblerDialect(0); 4830 return false; 4831 } else if (IDVal.startswith(".intel_syntax")) { 4832 getParser().setAssemblerDialect(1); 4833 if (getLexer().isNot(AsmToken::EndOfStatement)) { 4834 if (Parser.getTok().getString() == "noprefix") 4835 Parser.Lex(); 4836 else if (Parser.getTok().getString() == "prefix") 4837 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not " 4838 "supported: registers must not have " 4839 "a '%' prefix in .intel_syntax"); 4840 } 4841 return false; 4842 } else if (IDVal == ".nops") 4843 return parseDirectiveNops(DirectiveID.getLoc()); 4844 else if (IDVal == ".even") 4845 return parseDirectiveEven(DirectiveID.getLoc()); 4846 else if (IDVal == ".cv_fpo_proc") 4847 return parseDirectiveFPOProc(DirectiveID.getLoc()); 4848 else if (IDVal == ".cv_fpo_setframe") 4849 return parseDirectiveFPOSetFrame(DirectiveID.getLoc()); 4850 else if (IDVal == ".cv_fpo_pushreg") 4851 return parseDirectiveFPOPushReg(DirectiveID.getLoc()); 4852 else if (IDVal == ".cv_fpo_stackalloc") 4853 return parseDirectiveFPOStackAlloc(DirectiveID.getLoc()); 4854 else if (IDVal == ".cv_fpo_stackalign") 4855 return parseDirectiveFPOStackAlign(DirectiveID.getLoc()); 4856 else if (IDVal == ".cv_fpo_endprologue") 4857 return parseDirectiveFPOEndPrologue(DirectiveID.getLoc()); 4858 else if (IDVal == ".cv_fpo_endproc") 4859 return parseDirectiveFPOEndProc(DirectiveID.getLoc()); 4860 else if (IDVal == ".seh_pushreg" || 4861 (Parser.isParsingMasm() && IDVal.equals_insensitive(".pushreg"))) 4862 return parseDirectiveSEHPushReg(DirectiveID.getLoc()); 4863 else if (IDVal == ".seh_setframe" || 4864 (Parser.isParsingMasm() && IDVal.equals_insensitive(".setframe"))) 4865 return parseDirectiveSEHSetFrame(DirectiveID.getLoc()); 4866 else if (IDVal == ".seh_savereg" || 4867 (Parser.isParsingMasm() && IDVal.equals_insensitive(".savereg"))) 4868 return parseDirectiveSEHSaveReg(DirectiveID.getLoc()); 4869 else if (IDVal == ".seh_savexmm" || 4870 (Parser.isParsingMasm() && IDVal.equals_insensitive(".savexmm128"))) 4871 return parseDirectiveSEHSaveXMM(DirectiveID.getLoc()); 4872 else if (IDVal == ".seh_pushframe" || 4873 (Parser.isParsingMasm() && IDVal.equals_insensitive(".pushframe"))) 4874 return parseDirectiveSEHPushFrame(DirectiveID.getLoc()); 4875 4876 return true; 4877 } 4878 4879 bool X86AsmParser::parseDirectiveArch() { 4880 // Ignore .arch for now. 4881 getParser().parseStringToEndOfStatement(); 4882 return false; 4883 } 4884 4885 /// parseDirectiveNops 4886 /// ::= .nops size[, control] 4887 bool X86AsmParser::parseDirectiveNops(SMLoc L) { 4888 int64_t NumBytes = 0, Control = 0; 4889 SMLoc NumBytesLoc, ControlLoc; 4890 const MCSubtargetInfo& STI = getSTI(); 4891 NumBytesLoc = getTok().getLoc(); 4892 if (getParser().checkForValidSection() || 4893 getParser().parseAbsoluteExpression(NumBytes)) 4894 return true; 4895 4896 if (parseOptionalToken(AsmToken::Comma)) { 4897 ControlLoc = getTok().getLoc(); 4898 if (getParser().parseAbsoluteExpression(Control)) 4899 return true; 4900 } 4901 if (getParser().parseEOL()) 4902 return true; 4903 4904 if (NumBytes <= 0) { 4905 Error(NumBytesLoc, "'.nops' directive with non-positive size"); 4906 return false; 4907 } 4908 4909 if (Control < 0) { 4910 Error(ControlLoc, "'.nops' directive with negative NOP size"); 4911 return false; 4912 } 4913 4914 /// Emit nops 4915 getParser().getStreamer().emitNops(NumBytes, Control, L, STI); 4916 4917 return false; 4918 } 4919 4920 /// parseDirectiveEven 4921 /// ::= .even 4922 bool X86AsmParser::parseDirectiveEven(SMLoc L) { 4923 if (parseEOL()) 4924 return false; 4925 4926 const MCSection *Section = getStreamer().getCurrentSectionOnly(); 4927 if (!Section) { 4928 getStreamer().initSections(false, getSTI()); 4929 Section = getStreamer().getCurrentSectionOnly(); 4930 } 4931 if (Section->useCodeAlign()) 4932 getStreamer().emitCodeAlignment(2, &getSTI(), 0); 4933 else 4934 getStreamer().emitValueToAlignment(2, 0, 1, 0); 4935 return false; 4936 } 4937 4938 /// ParseDirectiveCode 4939 /// ::= .code16 | .code32 | .code64 4940 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) { 4941 MCAsmParser &Parser = getParser(); 4942 Code16GCC = false; 4943 if (IDVal == ".code16") { 4944 Parser.Lex(); 4945 if (!is16BitMode()) { 4946 SwitchMode(X86::Is16Bit); 4947 getParser().getStreamer().emitAssemblerFlag(MCAF_Code16); 4948 } 4949 } else if (IDVal == ".code16gcc") { 4950 // .code16gcc parses as if in 32-bit mode, but emits code in 16-bit mode. 4951 Parser.Lex(); 4952 Code16GCC = true; 4953 if (!is16BitMode()) { 4954 SwitchMode(X86::Is16Bit); 4955 getParser().getStreamer().emitAssemblerFlag(MCAF_Code16); 4956 } 4957 } else if (IDVal == ".code32") { 4958 Parser.Lex(); 4959 if (!is32BitMode()) { 4960 SwitchMode(X86::Is32Bit); 4961 getParser().getStreamer().emitAssemblerFlag(MCAF_Code32); 4962 } 4963 } else if (IDVal == ".code64") { 4964 Parser.Lex(); 4965 if (!is64BitMode()) { 4966 SwitchMode(X86::Is64Bit); 4967 getParser().getStreamer().emitAssemblerFlag(MCAF_Code64); 4968 } 4969 } else { 4970 Error(L, "unknown directive " + IDVal); 4971 return false; 4972 } 4973 4974 return false; 4975 } 4976 4977 // .cv_fpo_proc foo 4978 bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) { 4979 MCAsmParser &Parser = getParser(); 4980 StringRef ProcName; 4981 int64_t ParamsSize; 4982 if (Parser.parseIdentifier(ProcName)) 4983 return Parser.TokError("expected symbol name"); 4984 if (Parser.parseIntToken(ParamsSize, "expected parameter byte count")) 4985 return true; 4986 if (!isUIntN(32, ParamsSize)) 4987 return Parser.TokError("parameters size out of range"); 4988 if (parseEOL()) 4989 return true; 4990 MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName); 4991 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L); 4992 } 4993 4994 // .cv_fpo_setframe ebp 4995 bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) { 4996 unsigned Reg; 4997 SMLoc DummyLoc; 4998 if (ParseRegister(Reg, DummyLoc, DummyLoc) || parseEOL()) 4999 return true; 5000 return getTargetStreamer().emitFPOSetFrame(Reg, L); 5001 } 5002 5003 // .cv_fpo_pushreg ebx 5004 bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) { 5005 unsigned Reg; 5006 SMLoc DummyLoc; 5007 if (ParseRegister(Reg, DummyLoc, DummyLoc) || parseEOL()) 5008 return true; 5009 return getTargetStreamer().emitFPOPushReg(Reg, L); 5010 } 5011 5012 // .cv_fpo_stackalloc 20 5013 bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) { 5014 MCAsmParser &Parser = getParser(); 5015 int64_t Offset; 5016 if (Parser.parseIntToken(Offset, "expected offset") || parseEOL()) 5017 return true; 5018 return getTargetStreamer().emitFPOStackAlloc(Offset, L); 5019 } 5020 5021 // .cv_fpo_stackalign 8 5022 bool X86AsmParser::parseDirectiveFPOStackAlign(SMLoc L) { 5023 MCAsmParser &Parser = getParser(); 5024 int64_t Offset; 5025 if (Parser.parseIntToken(Offset, "expected offset") || parseEOL()) 5026 return true; 5027 return getTargetStreamer().emitFPOStackAlign(Offset, L); 5028 } 5029 5030 // .cv_fpo_endprologue 5031 bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) { 5032 MCAsmParser &Parser = getParser(); 5033 if (Parser.parseEOL()) 5034 return true; 5035 return getTargetStreamer().emitFPOEndPrologue(L); 5036 } 5037 5038 // .cv_fpo_endproc 5039 bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) { 5040 MCAsmParser &Parser = getParser(); 5041 if (Parser.parseEOL()) 5042 return true; 5043 return getTargetStreamer().emitFPOEndProc(L); 5044 } 5045 5046 bool X86AsmParser::parseSEHRegisterNumber(unsigned RegClassID, 5047 unsigned &RegNo) { 5048 SMLoc startLoc = getLexer().getLoc(); 5049 const MCRegisterInfo *MRI = getContext().getRegisterInfo(); 5050 5051 // Try parsing the argument as a register first. 5052 if (getLexer().getTok().isNot(AsmToken::Integer)) { 5053 SMLoc endLoc; 5054 if (ParseRegister(RegNo, startLoc, endLoc)) 5055 return true; 5056 5057 if (!X86MCRegisterClasses[RegClassID].contains(RegNo)) { 5058 return Error(startLoc, 5059 "register is not supported for use with this directive"); 5060 } 5061 } else { 5062 // Otherwise, an integer number matching the encoding of the desired 5063 // register may appear. 5064 int64_t EncodedReg; 5065 if (getParser().parseAbsoluteExpression(EncodedReg)) 5066 return true; 5067 5068 // The SEH register number is the same as the encoding register number. Map 5069 // from the encoding back to the LLVM register number. 5070 RegNo = 0; 5071 for (MCPhysReg Reg : X86MCRegisterClasses[RegClassID]) { 5072 if (MRI->getEncodingValue(Reg) == EncodedReg) { 5073 RegNo = Reg; 5074 break; 5075 } 5076 } 5077 if (RegNo == 0) { 5078 return Error(startLoc, 5079 "incorrect register number for use with this directive"); 5080 } 5081 } 5082 5083 return false; 5084 } 5085 5086 bool X86AsmParser::parseDirectiveSEHPushReg(SMLoc Loc) { 5087 unsigned Reg = 0; 5088 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg)) 5089 return true; 5090 5091 if (getLexer().isNot(AsmToken::EndOfStatement)) 5092 return TokError("unexpected token in directive"); 5093 5094 getParser().Lex(); 5095 getStreamer().emitWinCFIPushReg(Reg, Loc); 5096 return false; 5097 } 5098 5099 bool X86AsmParser::parseDirectiveSEHSetFrame(SMLoc Loc) { 5100 unsigned Reg = 0; 5101 int64_t Off; 5102 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg)) 5103 return true; 5104 if (getLexer().isNot(AsmToken::Comma)) 5105 return TokError("you must specify a stack pointer offset"); 5106 5107 getParser().Lex(); 5108 if (getParser().parseAbsoluteExpression(Off)) 5109 return true; 5110 5111 if (getLexer().isNot(AsmToken::EndOfStatement)) 5112 return TokError("unexpected token in directive"); 5113 5114 getParser().Lex(); 5115 getStreamer().emitWinCFISetFrame(Reg, Off, Loc); 5116 return false; 5117 } 5118 5119 bool X86AsmParser::parseDirectiveSEHSaveReg(SMLoc Loc) { 5120 unsigned Reg = 0; 5121 int64_t Off; 5122 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg)) 5123 return true; 5124 if (getLexer().isNot(AsmToken::Comma)) 5125 return TokError("you must specify an offset on the stack"); 5126 5127 getParser().Lex(); 5128 if (getParser().parseAbsoluteExpression(Off)) 5129 return true; 5130 5131 if (getLexer().isNot(AsmToken::EndOfStatement)) 5132 return TokError("unexpected token in directive"); 5133 5134 getParser().Lex(); 5135 getStreamer().emitWinCFISaveReg(Reg, Off, Loc); 5136 return false; 5137 } 5138 5139 bool X86AsmParser::parseDirectiveSEHSaveXMM(SMLoc Loc) { 5140 unsigned Reg = 0; 5141 int64_t Off; 5142 if (parseSEHRegisterNumber(X86::VR128XRegClassID, Reg)) 5143 return true; 5144 if (getLexer().isNot(AsmToken::Comma)) 5145 return TokError("you must specify an offset on the stack"); 5146 5147 getParser().Lex(); 5148 if (getParser().parseAbsoluteExpression(Off)) 5149 return true; 5150 5151 if (getLexer().isNot(AsmToken::EndOfStatement)) 5152 return TokError("unexpected token in directive"); 5153 5154 getParser().Lex(); 5155 getStreamer().emitWinCFISaveXMM(Reg, Off, Loc); 5156 return false; 5157 } 5158 5159 bool X86AsmParser::parseDirectiveSEHPushFrame(SMLoc Loc) { 5160 bool Code = false; 5161 StringRef CodeID; 5162 if (getLexer().is(AsmToken::At)) { 5163 SMLoc startLoc = getLexer().getLoc(); 5164 getParser().Lex(); 5165 if (!getParser().parseIdentifier(CodeID)) { 5166 if (CodeID != "code") 5167 return Error(startLoc, "expected @code"); 5168 Code = true; 5169 } 5170 } 5171 5172 if (getLexer().isNot(AsmToken::EndOfStatement)) 5173 return TokError("unexpected token in directive"); 5174 5175 getParser().Lex(); 5176 getStreamer().emitWinCFIPushFrame(Code, Loc); 5177 return false; 5178 } 5179 5180 // Force static initialization. 5181 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeX86AsmParser() { 5182 RegisterMCAsmParser<X86AsmParser> X(getTheX86_32Target()); 5183 RegisterMCAsmParser<X86AsmParser> Y(getTheX86_64Target()); 5184 } 5185 5186 #define GET_REGISTER_MATCHER 5187 #define GET_MATCHER_IMPLEMENTATION 5188 #define GET_SUBTARGET_FEATURE_NAME 5189 #include "X86GenAsmMatcher.inc" 5190