1 //===-- X86AsmParser.cpp - Parse X86 assembly to MCInst instructions ------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "InstPrinter/X86IntelInstPrinter.h" 11 #include "MCTargetDesc/X86BaseInfo.h" 12 #include "MCTargetDesc/X86TargetStreamer.h" 13 #include "X86AsmInstrumentation.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/Support/SourceMgr.h" 35 #include "llvm/Support/TargetRegistry.h" 36 #include "llvm/Support/raw_ostream.h" 37 #include <algorithm> 38 #include <memory> 39 40 using namespace llvm; 41 42 static bool checkScale(unsigned Scale, StringRef &ErrMsg) { 43 if (Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) { 44 ErrMsg = "scale factor in address must be 1, 2, 4 or 8"; 45 return true; 46 } 47 return false; 48 } 49 50 namespace { 51 52 static const char OpPrecedence[] = { 53 0, // IC_OR 54 1, // IC_XOR 55 2, // IC_AND 56 3, // IC_LSHIFT 57 3, // IC_RSHIFT 58 4, // IC_PLUS 59 4, // IC_MINUS 60 5, // IC_MULTIPLY 61 5, // IC_DIVIDE 62 5, // IC_MOD 63 6, // IC_NOT 64 7, // IC_NEG 65 8, // IC_RPAREN 66 9, // IC_LPAREN 67 0, // IC_IMM 68 0 // IC_REGISTER 69 }; 70 71 class X86AsmParser : public MCTargetAsmParser { 72 ParseInstructionInfo *InstInfo; 73 std::unique_ptr<X86AsmInstrumentation> Instrumentation; 74 bool Code16GCC; 75 76 private: 77 SMLoc consumeToken() { 78 MCAsmParser &Parser = getParser(); 79 SMLoc Result = Parser.getTok().getLoc(); 80 Parser.Lex(); 81 return Result; 82 } 83 84 X86TargetStreamer &getTargetStreamer() { 85 assert(getParser().getStreamer().getTargetStreamer() && 86 "do not have a target streamer"); 87 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); 88 return static_cast<X86TargetStreamer &>(TS); 89 } 90 91 unsigned MatchInstruction(const OperandVector &Operands, MCInst &Inst, 92 uint64_t &ErrorInfo, bool matchingInlineAsm, 93 unsigned VariantID = 0) { 94 // In Code16GCC mode, match as 32-bit. 95 if (Code16GCC) 96 SwitchMode(X86::Mode32Bit); 97 unsigned rv = MatchInstructionImpl(Operands, Inst, ErrorInfo, 98 matchingInlineAsm, VariantID); 99 if (Code16GCC) 100 SwitchMode(X86::Mode16Bit); 101 return rv; 102 } 103 104 enum InfixCalculatorTok { 105 IC_OR = 0, 106 IC_XOR, 107 IC_AND, 108 IC_LSHIFT, 109 IC_RSHIFT, 110 IC_PLUS, 111 IC_MINUS, 112 IC_MULTIPLY, 113 IC_DIVIDE, 114 IC_MOD, 115 IC_NOT, 116 IC_NEG, 117 IC_RPAREN, 118 IC_LPAREN, 119 IC_IMM, 120 IC_REGISTER 121 }; 122 123 enum IntelOperatorKind { 124 IOK_INVALID = 0, 125 IOK_LENGTH, 126 IOK_SIZE, 127 IOK_TYPE, 128 IOK_OFFSET 129 }; 130 131 class InfixCalculator { 132 typedef std::pair< InfixCalculatorTok, int64_t > ICToken; 133 SmallVector<InfixCalculatorTok, 4> InfixOperatorStack; 134 SmallVector<ICToken, 4> PostfixStack; 135 136 bool isUnaryOperator(const InfixCalculatorTok Op) { 137 return Op == IC_NEG || Op == IC_NOT; 138 } 139 140 public: 141 int64_t popOperand() { 142 assert (!PostfixStack.empty() && "Poped an empty stack!"); 143 ICToken Op = PostfixStack.pop_back_val(); 144 if (!(Op.first == IC_IMM || Op.first == IC_REGISTER)) 145 return -1; // The invalid Scale value will be caught later by checkScale 146 return Op.second; 147 } 148 void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) { 149 assert ((Op == IC_IMM || Op == IC_REGISTER) && 150 "Unexpected operand!"); 151 PostfixStack.push_back(std::make_pair(Op, Val)); 152 } 153 154 void popOperator() { InfixOperatorStack.pop_back(); } 155 void pushOperator(InfixCalculatorTok Op) { 156 // Push the new operator if the stack is empty. 157 if (InfixOperatorStack.empty()) { 158 InfixOperatorStack.push_back(Op); 159 return; 160 } 161 162 // Push the new operator if it has a higher precedence than the operator 163 // on the top of the stack or the operator on the top of the stack is a 164 // left parentheses. 165 unsigned Idx = InfixOperatorStack.size() - 1; 166 InfixCalculatorTok StackOp = InfixOperatorStack[Idx]; 167 if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) { 168 InfixOperatorStack.push_back(Op); 169 return; 170 } 171 172 // The operator on the top of the stack has higher precedence than the 173 // new operator. 174 unsigned ParenCount = 0; 175 while (1) { 176 // Nothing to process. 177 if (InfixOperatorStack.empty()) 178 break; 179 180 Idx = InfixOperatorStack.size() - 1; 181 StackOp = InfixOperatorStack[Idx]; 182 if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount)) 183 break; 184 185 // If we have an even parentheses count and we see a left parentheses, 186 // then stop processing. 187 if (!ParenCount && StackOp == IC_LPAREN) 188 break; 189 190 if (StackOp == IC_RPAREN) { 191 ++ParenCount; 192 InfixOperatorStack.pop_back(); 193 } else if (StackOp == IC_LPAREN) { 194 --ParenCount; 195 InfixOperatorStack.pop_back(); 196 } else { 197 InfixOperatorStack.pop_back(); 198 PostfixStack.push_back(std::make_pair(StackOp, 0)); 199 } 200 } 201 // Push the new operator. 202 InfixOperatorStack.push_back(Op); 203 } 204 205 int64_t execute() { 206 // Push any remaining operators onto the postfix stack. 207 while (!InfixOperatorStack.empty()) { 208 InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val(); 209 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN) 210 PostfixStack.push_back(std::make_pair(StackOp, 0)); 211 } 212 213 if (PostfixStack.empty()) 214 return 0; 215 216 SmallVector<ICToken, 16> OperandStack; 217 for (unsigned i = 0, e = PostfixStack.size(); i != e; ++i) { 218 ICToken Op = PostfixStack[i]; 219 if (Op.first == IC_IMM || Op.first == IC_REGISTER) { 220 OperandStack.push_back(Op); 221 } else if (isUnaryOperator(Op.first)) { 222 assert (OperandStack.size() > 0 && "Too few operands."); 223 ICToken Operand = OperandStack.pop_back_val(); 224 assert (Operand.first == IC_IMM && 225 "Unary operation with a register!"); 226 switch (Op.first) { 227 default: 228 report_fatal_error("Unexpected operator!"); 229 break; 230 case IC_NEG: 231 OperandStack.push_back(std::make_pair(IC_IMM, -Operand.second)); 232 break; 233 case IC_NOT: 234 OperandStack.push_back(std::make_pair(IC_IMM, ~Operand.second)); 235 break; 236 } 237 } else { 238 assert (OperandStack.size() > 1 && "Too few operands."); 239 int64_t Val; 240 ICToken Op2 = OperandStack.pop_back_val(); 241 ICToken Op1 = OperandStack.pop_back_val(); 242 switch (Op.first) { 243 default: 244 report_fatal_error("Unexpected operator!"); 245 break; 246 case IC_PLUS: 247 Val = Op1.second + Op2.second; 248 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 249 break; 250 case IC_MINUS: 251 Val = Op1.second - Op2.second; 252 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 253 break; 254 case IC_MULTIPLY: 255 assert (Op1.first == IC_IMM && Op2.first == IC_IMM && 256 "Multiply operation with an immediate and a register!"); 257 Val = Op1.second * Op2.second; 258 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 259 break; 260 case IC_DIVIDE: 261 assert (Op1.first == IC_IMM && Op2.first == IC_IMM && 262 "Divide operation with an immediate and a register!"); 263 assert (Op2.second != 0 && "Division by zero!"); 264 Val = Op1.second / Op2.second; 265 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 266 break; 267 case IC_MOD: 268 assert (Op1.first == IC_IMM && Op2.first == IC_IMM && 269 "Modulo operation with an immediate and a register!"); 270 Val = Op1.second % Op2.second; 271 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 272 break; 273 case IC_OR: 274 assert (Op1.first == IC_IMM && Op2.first == IC_IMM && 275 "Or operation with an immediate and a register!"); 276 Val = Op1.second | Op2.second; 277 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 278 break; 279 case IC_XOR: 280 assert(Op1.first == IC_IMM && Op2.first == IC_IMM && 281 "Xor operation with an immediate and a register!"); 282 Val = Op1.second ^ Op2.second; 283 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 284 break; 285 case IC_AND: 286 assert (Op1.first == IC_IMM && Op2.first == IC_IMM && 287 "And operation with an immediate and a register!"); 288 Val = Op1.second & Op2.second; 289 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 290 break; 291 case IC_LSHIFT: 292 assert (Op1.first == IC_IMM && Op2.first == IC_IMM && 293 "Left shift operation with an immediate and a register!"); 294 Val = Op1.second << Op2.second; 295 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 296 break; 297 case IC_RSHIFT: 298 assert (Op1.first == IC_IMM && Op2.first == IC_IMM && 299 "Right shift operation with an immediate and a register!"); 300 Val = Op1.second >> Op2.second; 301 OperandStack.push_back(std::make_pair(IC_IMM, Val)); 302 break; 303 } 304 } 305 } 306 assert (OperandStack.size() == 1 && "Expected a single result."); 307 return OperandStack.pop_back_val().second; 308 } 309 }; 310 311 enum IntelExprState { 312 IES_INIT, 313 IES_OR, 314 IES_XOR, 315 IES_AND, 316 IES_LSHIFT, 317 IES_RSHIFT, 318 IES_PLUS, 319 IES_MINUS, 320 IES_NOT, 321 IES_MULTIPLY, 322 IES_DIVIDE, 323 IES_MOD, 324 IES_LBRAC, 325 IES_RBRAC, 326 IES_LPAREN, 327 IES_RPAREN, 328 IES_REGISTER, 329 IES_INTEGER, 330 IES_IDENTIFIER, 331 IES_ERROR 332 }; 333 334 class IntelExprStateMachine { 335 IntelExprState State, PrevState; 336 unsigned BaseReg, IndexReg, TmpReg, Scale; 337 int64_t Imm; 338 const MCExpr *Sym; 339 StringRef SymName; 340 InfixCalculator IC; 341 InlineAsmIdentifierInfo Info; 342 short BracCount; 343 bool MemExpr; 344 345 public: 346 IntelExprStateMachine() 347 : State(IES_INIT), PrevState(IES_ERROR), BaseReg(0), IndexReg(0), 348 TmpReg(0), Scale(1), Imm(0), Sym(nullptr), BracCount(0), 349 MemExpr(false) {} 350 351 void addImm(int64_t imm) { Imm += imm; } 352 short getBracCount() { return BracCount; } 353 bool isMemExpr() { return MemExpr; } 354 unsigned getBaseReg() { return BaseReg; } 355 unsigned getIndexReg() { return IndexReg; } 356 unsigned getScale() { return Scale; } 357 const MCExpr *getSym() { return Sym; } 358 StringRef getSymName() { return SymName; } 359 int64_t getImm() { return Imm + IC.execute(); } 360 bool isValidEndState() { 361 return State == IES_RBRAC || State == IES_INTEGER; 362 } 363 bool hadError() { return State == IES_ERROR; } 364 InlineAsmIdentifierInfo &getIdentifierInfo() { return Info; } 365 366 void onOr() { 367 IntelExprState CurrState = State; 368 switch (State) { 369 default: 370 State = IES_ERROR; 371 break; 372 case IES_INTEGER: 373 case IES_RPAREN: 374 case IES_REGISTER: 375 State = IES_OR; 376 IC.pushOperator(IC_OR); 377 break; 378 } 379 PrevState = CurrState; 380 } 381 void onXor() { 382 IntelExprState CurrState = State; 383 switch (State) { 384 default: 385 State = IES_ERROR; 386 break; 387 case IES_INTEGER: 388 case IES_RPAREN: 389 case IES_REGISTER: 390 State = IES_XOR; 391 IC.pushOperator(IC_XOR); 392 break; 393 } 394 PrevState = CurrState; 395 } 396 void onAnd() { 397 IntelExprState CurrState = State; 398 switch (State) { 399 default: 400 State = IES_ERROR; 401 break; 402 case IES_INTEGER: 403 case IES_RPAREN: 404 case IES_REGISTER: 405 State = IES_AND; 406 IC.pushOperator(IC_AND); 407 break; 408 } 409 PrevState = CurrState; 410 } 411 void onLShift() { 412 IntelExprState CurrState = State; 413 switch (State) { 414 default: 415 State = IES_ERROR; 416 break; 417 case IES_INTEGER: 418 case IES_RPAREN: 419 case IES_REGISTER: 420 State = IES_LSHIFT; 421 IC.pushOperator(IC_LSHIFT); 422 break; 423 } 424 PrevState = CurrState; 425 } 426 void onRShift() { 427 IntelExprState CurrState = State; 428 switch (State) { 429 default: 430 State = IES_ERROR; 431 break; 432 case IES_INTEGER: 433 case IES_RPAREN: 434 case IES_REGISTER: 435 State = IES_RSHIFT; 436 IC.pushOperator(IC_RSHIFT); 437 break; 438 } 439 PrevState = CurrState; 440 } 441 bool onPlus(StringRef &ErrMsg) { 442 IntelExprState CurrState = State; 443 switch (State) { 444 default: 445 State = IES_ERROR; 446 break; 447 case IES_INTEGER: 448 case IES_RPAREN: 449 case IES_REGISTER: 450 State = IES_PLUS; 451 IC.pushOperator(IC_PLUS); 452 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) { 453 // If we already have a BaseReg, then assume this is the IndexReg with 454 // a scale of 1. 455 if (!BaseReg) { 456 BaseReg = TmpReg; 457 } else { 458 if (IndexReg) { 459 ErrMsg = "BaseReg/IndexReg already set!"; 460 return true; 461 } 462 IndexReg = TmpReg; 463 Scale = 1; 464 } 465 } 466 break; 467 } 468 PrevState = CurrState; 469 return false; 470 } 471 bool onMinus(StringRef &ErrMsg) { 472 IntelExprState CurrState = State; 473 switch (State) { 474 default: 475 State = IES_ERROR; 476 break; 477 case IES_OR: 478 case IES_XOR: 479 case IES_AND: 480 case IES_LSHIFT: 481 case IES_RSHIFT: 482 case IES_PLUS: 483 case IES_NOT: 484 case IES_MULTIPLY: 485 case IES_DIVIDE: 486 case IES_MOD: 487 case IES_LPAREN: 488 case IES_RPAREN: 489 case IES_LBRAC: 490 case IES_RBRAC: 491 case IES_INTEGER: 492 case IES_REGISTER: 493 case IES_INIT: 494 State = IES_MINUS; 495 // push minus operator if it is not a negate operator 496 if (CurrState == IES_REGISTER || CurrState == IES_RPAREN || 497 CurrState == IES_INTEGER || CurrState == IES_RBRAC) 498 IC.pushOperator(IC_MINUS); 499 else if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) { 500 // We have negate operator for Scale: it's illegal 501 ErrMsg = "Scale can't be negative"; 502 return true; 503 } else 504 IC.pushOperator(IC_NEG); 505 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) { 506 // If we already have a BaseReg, then assume this is the IndexReg with 507 // a scale of 1. 508 if (!BaseReg) { 509 BaseReg = TmpReg; 510 } else { 511 if (IndexReg) { 512 ErrMsg = "BaseReg/IndexReg already set!"; 513 return true; 514 } 515 IndexReg = TmpReg; 516 Scale = 1; 517 } 518 } 519 break; 520 } 521 PrevState = CurrState; 522 return false; 523 } 524 void onNot() { 525 IntelExprState CurrState = State; 526 switch (State) { 527 default: 528 State = IES_ERROR; 529 break; 530 case IES_OR: 531 case IES_XOR: 532 case IES_AND: 533 case IES_LSHIFT: 534 case IES_RSHIFT: 535 case IES_PLUS: 536 case IES_MINUS: 537 case IES_NOT: 538 case IES_MULTIPLY: 539 case IES_DIVIDE: 540 case IES_MOD: 541 case IES_LPAREN: 542 case IES_LBRAC: 543 case IES_INIT: 544 State = IES_NOT; 545 IC.pushOperator(IC_NOT); 546 break; 547 } 548 PrevState = CurrState; 549 } 550 551 bool onRegister(unsigned Reg, StringRef &ErrMsg) { 552 IntelExprState CurrState = State; 553 switch (State) { 554 default: 555 State = IES_ERROR; 556 break; 557 case IES_PLUS: 558 case IES_LPAREN: 559 case IES_LBRAC: 560 State = IES_REGISTER; 561 TmpReg = Reg; 562 IC.pushOperand(IC_REGISTER); 563 break; 564 case IES_MULTIPLY: 565 // Index Register - Scale * Register 566 if (PrevState == IES_INTEGER) { 567 if (IndexReg) { 568 ErrMsg = "BaseReg/IndexReg already set!"; 569 return true; 570 } 571 State = IES_REGISTER; 572 IndexReg = Reg; 573 // Get the scale and replace the 'Scale * Register' with '0'. 574 Scale = IC.popOperand(); 575 if (checkScale(Scale, ErrMsg)) 576 return true; 577 IC.pushOperand(IC_IMM); 578 IC.popOperator(); 579 } else { 580 State = IES_ERROR; 581 } 582 break; 583 } 584 PrevState = CurrState; 585 return false; 586 } 587 bool onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName, 588 const InlineAsmIdentifierInfo &IDInfo, 589 bool ParsingInlineAsm, StringRef &ErrMsg) { 590 // InlineAsm: Treat an enum value as an integer 591 if (ParsingInlineAsm) 592 if (IDInfo.isKind(InlineAsmIdentifierInfo::IK_EnumVal)) 593 return onInteger(IDInfo.Enum.EnumVal, ErrMsg); 594 // Treat a symbolic constant like an integer 595 if (auto *CE = dyn_cast<MCConstantExpr>(SymRef)) 596 return onInteger(CE->getValue(), ErrMsg); 597 PrevState = State; 598 bool HasSymbol = Sym != nullptr; 599 switch (State) { 600 default: 601 State = IES_ERROR; 602 break; 603 case IES_PLUS: 604 case IES_MINUS: 605 case IES_NOT: 606 case IES_INIT: 607 case IES_LBRAC: 608 MemExpr = true; 609 State = IES_INTEGER; 610 Sym = SymRef; 611 SymName = SymRefName; 612 IC.pushOperand(IC_IMM); 613 if (ParsingInlineAsm) 614 Info = IDInfo; 615 break; 616 } 617 if (HasSymbol) 618 ErrMsg = "cannot use more than one symbol in memory operand"; 619 return HasSymbol; 620 } 621 bool onInteger(int64_t TmpInt, StringRef &ErrMsg) { 622 IntelExprState CurrState = State; 623 switch (State) { 624 default: 625 State = IES_ERROR; 626 break; 627 case IES_PLUS: 628 case IES_MINUS: 629 case IES_NOT: 630 case IES_OR: 631 case IES_XOR: 632 case IES_AND: 633 case IES_LSHIFT: 634 case IES_RSHIFT: 635 case IES_DIVIDE: 636 case IES_MOD: 637 case IES_MULTIPLY: 638 case IES_LPAREN: 639 case IES_INIT: 640 case IES_LBRAC: 641 State = IES_INTEGER; 642 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) { 643 // Index Register - Register * Scale 644 if (IndexReg) { 645 ErrMsg = "BaseReg/IndexReg already set!"; 646 return true; 647 } 648 IndexReg = TmpReg; 649 Scale = TmpInt; 650 if (checkScale(Scale, ErrMsg)) 651 return true; 652 // Get the scale and replace the 'Register * Scale' with '0'. 653 IC.popOperator(); 654 } else { 655 IC.pushOperand(IC_IMM, TmpInt); 656 } 657 break; 658 } 659 PrevState = CurrState; 660 return false; 661 } 662 void onStar() { 663 PrevState = State; 664 switch (State) { 665 default: 666 State = IES_ERROR; 667 break; 668 case IES_INTEGER: 669 case IES_REGISTER: 670 case IES_RPAREN: 671 State = IES_MULTIPLY; 672 IC.pushOperator(IC_MULTIPLY); 673 break; 674 } 675 } 676 void onDivide() { 677 PrevState = State; 678 switch (State) { 679 default: 680 State = IES_ERROR; 681 break; 682 case IES_INTEGER: 683 case IES_RPAREN: 684 State = IES_DIVIDE; 685 IC.pushOperator(IC_DIVIDE); 686 break; 687 } 688 } 689 void onMod() { 690 PrevState = State; 691 switch (State) { 692 default: 693 State = IES_ERROR; 694 break; 695 case IES_INTEGER: 696 case IES_RPAREN: 697 State = IES_MOD; 698 IC.pushOperator(IC_MOD); 699 break; 700 } 701 } 702 bool onLBrac() { 703 if (BracCount) 704 return true; 705 PrevState = State; 706 switch (State) { 707 default: 708 State = IES_ERROR; 709 break; 710 case IES_RBRAC: 711 case IES_INTEGER: 712 case IES_RPAREN: 713 State = IES_PLUS; 714 IC.pushOperator(IC_PLUS); 715 break; 716 case IES_INIT: 717 assert(!BracCount && "BracCount should be zero on parsing's start"); 718 State = IES_LBRAC; 719 break; 720 } 721 MemExpr = true; 722 BracCount++; 723 return false; 724 } 725 bool onRBrac() { 726 IntelExprState CurrState = State; 727 switch (State) { 728 default: 729 State = IES_ERROR; 730 break; 731 case IES_INTEGER: 732 case IES_REGISTER: 733 case IES_RPAREN: 734 if (BracCount-- != 1) 735 return true; 736 State = IES_RBRAC; 737 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) { 738 // If we already have a BaseReg, then assume this is the IndexReg with 739 // a scale of 1. 740 if (!BaseReg) { 741 BaseReg = TmpReg; 742 } else { 743 assert (!IndexReg && "BaseReg/IndexReg already set!"); 744 IndexReg = TmpReg; 745 Scale = 1; 746 } 747 } 748 break; 749 } 750 PrevState = CurrState; 751 return false; 752 } 753 void onLParen() { 754 IntelExprState CurrState = State; 755 switch (State) { 756 default: 757 State = IES_ERROR; 758 break; 759 case IES_PLUS: 760 case IES_MINUS: 761 case IES_NOT: 762 case IES_OR: 763 case IES_XOR: 764 case IES_AND: 765 case IES_LSHIFT: 766 case IES_RSHIFT: 767 case IES_MULTIPLY: 768 case IES_DIVIDE: 769 case IES_MOD: 770 case IES_LPAREN: 771 case IES_INIT: 772 case IES_LBRAC: 773 State = IES_LPAREN; 774 IC.pushOperator(IC_LPAREN); 775 break; 776 } 777 PrevState = CurrState; 778 } 779 void onRParen() { 780 PrevState = State; 781 switch (State) { 782 default: 783 State = IES_ERROR; 784 break; 785 case IES_INTEGER: 786 case IES_REGISTER: 787 case IES_RPAREN: 788 State = IES_RPAREN; 789 IC.pushOperator(IC_RPAREN); 790 break; 791 } 792 } 793 }; 794 795 bool Error(SMLoc L, const Twine &Msg, SMRange Range = None, 796 bool MatchingInlineAsm = false) { 797 MCAsmParser &Parser = getParser(); 798 if (MatchingInlineAsm) { 799 if (!getLexer().isAtStartOfStatement()) 800 Parser.eatToEndOfStatement(); 801 return false; 802 } 803 return Parser.Error(L, Msg, Range); 804 } 805 806 std::nullptr_t ErrorOperand(SMLoc Loc, StringRef Msg) { 807 Error(Loc, Msg); 808 return nullptr; 809 } 810 811 std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc); 812 std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc); 813 bool IsSIReg(unsigned Reg); 814 unsigned GetSIDIForRegClass(unsigned RegClassID, unsigned Reg, bool IsSIReg); 815 void 816 AddDefaultSrcDestOperands(OperandVector &Operands, 817 std::unique_ptr<llvm::MCParsedAsmOperand> &&Src, 818 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst); 819 bool VerifyAndAdjustOperands(OperandVector &OrigOperands, 820 OperandVector &FinalOperands); 821 std::unique_ptr<X86Operand> ParseOperand(); 822 std::unique_ptr<X86Operand> ParseATTOperand(); 823 std::unique_ptr<X86Operand> ParseIntelOperand(); 824 std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator(); 825 bool ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End); 826 unsigned IdentifyIntelInlineAsmOperator(StringRef Name); 827 unsigned ParseIntelInlineAsmOperator(unsigned OpKind); 828 std::unique_ptr<X86Operand> ParseRoundingModeOp(SMLoc Start, SMLoc End); 829 bool ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM); 830 void RewriteIntelExpression(IntelExprStateMachine &SM, SMLoc Start, 831 SMLoc End); 832 bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End); 833 bool ParseIntelInlineAsmIdentifier(const MCExpr *&Val, StringRef &Identifier, 834 InlineAsmIdentifierInfo &Info, 835 bool IsUnevaluatedOperand, SMLoc &End); 836 837 std::unique_ptr<X86Operand> ParseMemOperand(unsigned SegReg, SMLoc StartLoc); 838 839 bool ParseIntelMemoryOperandSize(unsigned &Size); 840 std::unique_ptr<X86Operand> 841 CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, 842 unsigned IndexReg, unsigned Scale, SMLoc Start, 843 SMLoc End, unsigned Size, StringRef Identifier, 844 const InlineAsmIdentifierInfo &Info); 845 846 bool parseDirectiveEven(SMLoc L); 847 bool ParseDirectiveWord(unsigned Size, SMLoc L); 848 bool ParseDirectiveCode(StringRef IDVal, SMLoc L); 849 850 /// CodeView FPO data directives. 851 bool parseDirectiveFPOProc(SMLoc L); 852 bool parseDirectiveFPOSetFrame(SMLoc L); 853 bool parseDirectiveFPOPushReg(SMLoc L); 854 bool parseDirectiveFPOStackAlloc(SMLoc L); 855 bool parseDirectiveFPOEndPrologue(SMLoc L); 856 bool parseDirectiveFPOEndProc(SMLoc L); 857 bool parseDirectiveFPOData(SMLoc L); 858 859 bool validateInstruction(MCInst &Inst, const OperandVector &Ops); 860 bool processInstruction(MCInst &Inst, const OperandVector &Ops); 861 862 /// Wrapper around MCStreamer::EmitInstruction(). Possibly adds 863 /// instrumentation around Inst. 864 void EmitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out); 865 866 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 867 OperandVector &Operands, MCStreamer &Out, 868 uint64_t &ErrorInfo, 869 bool MatchingInlineAsm) override; 870 871 void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, OperandVector &Operands, 872 MCStreamer &Out, bool MatchingInlineAsm); 873 874 bool ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo, 875 bool MatchingInlineAsm); 876 877 bool MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode, 878 OperandVector &Operands, MCStreamer &Out, 879 uint64_t &ErrorInfo, 880 bool MatchingInlineAsm); 881 882 bool MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode, 883 OperandVector &Operands, MCStreamer &Out, 884 uint64_t &ErrorInfo, 885 bool MatchingInlineAsm); 886 887 bool OmitRegisterFromClobberLists(unsigned RegNo) override; 888 889 /// Parses AVX512 specific operand primitives: masked registers ({%k<NUM>}, {z}) 890 /// and memory broadcasting ({1to<NUM>}) primitives, updating Operands vector if required. 891 /// return false if no parsing errors occurred, true otherwise. 892 bool HandleAVX512Operand(OperandVector &Operands, 893 const MCParsedAsmOperand &Op); 894 895 bool ParseZ(std::unique_ptr<X86Operand> &Z, const SMLoc &StartLoc); 896 897 bool is64BitMode() const { 898 // FIXME: Can tablegen auto-generate this? 899 return getSTI().getFeatureBits()[X86::Mode64Bit]; 900 } 901 bool is32BitMode() const { 902 // FIXME: Can tablegen auto-generate this? 903 return getSTI().getFeatureBits()[X86::Mode32Bit]; 904 } 905 bool is16BitMode() const { 906 // FIXME: Can tablegen auto-generate this? 907 return getSTI().getFeatureBits()[X86::Mode16Bit]; 908 } 909 void SwitchMode(unsigned mode) { 910 MCSubtargetInfo &STI = copySTI(); 911 FeatureBitset AllModes({X86::Mode64Bit, X86::Mode32Bit, X86::Mode16Bit}); 912 FeatureBitset OldMode = STI.getFeatureBits() & AllModes; 913 uint64_t FB = ComputeAvailableFeatures( 914 STI.ToggleFeature(OldMode.flip(mode))); 915 setAvailableFeatures(FB); 916 917 assert(FeatureBitset({mode}) == (STI.getFeatureBits() & AllModes)); 918 } 919 920 unsigned getPointerWidth() { 921 if (is16BitMode()) return 16; 922 if (is32BitMode()) return 32; 923 if (is64BitMode()) return 64; 924 llvm_unreachable("invalid mode"); 925 } 926 927 bool isParsingIntelSyntax() { 928 return getParser().getAssemblerDialect(); 929 } 930 931 /// @name Auto-generated Matcher Functions 932 /// { 933 934 #define GET_ASSEMBLER_HEADER 935 #include "X86GenAsmMatcher.inc" 936 937 /// } 938 939 public: 940 941 X86AsmParser(const MCSubtargetInfo &sti, MCAsmParser &Parser, 942 const MCInstrInfo &mii, const MCTargetOptions &Options) 943 : MCTargetAsmParser(Options, sti, mii), InstInfo(nullptr), 944 Code16GCC(false) { 945 946 // Initialize the set of available features. 947 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits())); 948 Instrumentation.reset( 949 CreateX86AsmInstrumentation(Options, Parser.getContext(), STI)); 950 } 951 952 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 953 954 void SetFrameRegister(unsigned RegNo) override; 955 956 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 957 SMLoc NameLoc, OperandVector &Operands) override; 958 959 bool ParseDirective(AsmToken DirectiveID) override; 960 }; 961 } // end anonymous namespace 962 963 /// @name Auto-generated Match Functions 964 /// { 965 966 static unsigned MatchRegisterName(StringRef Name); 967 968 /// } 969 970 static bool CheckBaseRegAndIndexRegAndScale(unsigned BaseReg, unsigned IndexReg, 971 unsigned Scale, StringRef &ErrMsg) { 972 // If we have both a base register and an index register make sure they are 973 // both 64-bit or 32-bit registers. 974 // To support VSIB, IndexReg can be 128-bit or 256-bit registers. 975 976 if ((BaseReg == X86::RIP && IndexReg != 0) || (IndexReg == X86::RIP)) { 977 ErrMsg = "invalid base+index expression"; 978 return true; 979 } 980 if (BaseReg != 0 && IndexReg != 0) { 981 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) && 982 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) || 983 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg)) && 984 IndexReg != X86::RIZ) { 985 ErrMsg = "base register is 64-bit, but index register is not"; 986 return true; 987 } 988 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) && 989 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) || 990 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) && 991 IndexReg != X86::EIZ){ 992 ErrMsg = "base register is 32-bit, but index register is not"; 993 return true; 994 } 995 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) { 996 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) || 997 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) { 998 ErrMsg = "base register is 16-bit, but index register is not"; 999 return true; 1000 } 1001 if (((BaseReg == X86::BX || BaseReg == X86::BP) && 1002 IndexReg != X86::SI && IndexReg != X86::DI) || 1003 ((BaseReg == X86::SI || BaseReg == X86::DI) && 1004 IndexReg != X86::BX && IndexReg != X86::BP)) { 1005 ErrMsg = "invalid 16-bit base/index register combination"; 1006 return true; 1007 } 1008 } 1009 } 1010 return checkScale(Scale, ErrMsg); 1011 } 1012 1013 bool X86AsmParser::ParseRegister(unsigned &RegNo, 1014 SMLoc &StartLoc, SMLoc &EndLoc) { 1015 MCAsmParser &Parser = getParser(); 1016 RegNo = 0; 1017 const AsmToken &PercentTok = Parser.getTok(); 1018 StartLoc = PercentTok.getLoc(); 1019 1020 // If we encounter a %, ignore it. This code handles registers with and 1021 // without the prefix, unprefixed registers can occur in cfi directives. 1022 if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent)) 1023 Parser.Lex(); // Eat percent token. 1024 1025 const AsmToken &Tok = Parser.getTok(); 1026 EndLoc = Tok.getEndLoc(); 1027 1028 if (Tok.isNot(AsmToken::Identifier)) { 1029 if (isParsingIntelSyntax()) return true; 1030 return Error(StartLoc, "invalid register name", 1031 SMRange(StartLoc, EndLoc)); 1032 } 1033 1034 RegNo = MatchRegisterName(Tok.getString()); 1035 1036 // If the match failed, try the register name as lowercase. 1037 if (RegNo == 0) 1038 RegNo = MatchRegisterName(Tok.getString().lower()); 1039 1040 // The "flags" register cannot be referenced directly. 1041 // Treat it as an identifier instead. 1042 if (isParsingInlineAsm() && isParsingIntelSyntax() && RegNo == X86::EFLAGS) 1043 RegNo = 0; 1044 1045 if (!is64BitMode()) { 1046 // FIXME: This should be done using Requires<Not64BitMode> and 1047 // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also 1048 // checked. 1049 // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a 1050 // REX prefix. 1051 if (RegNo == X86::RIZ || 1052 X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) || 1053 X86II::isX86_64NonExtLowByteReg(RegNo) || 1054 X86II::isX86_64ExtendedReg(RegNo)) 1055 return Error(StartLoc, "register %" 1056 + Tok.getString() + " is only available in 64-bit mode", 1057 SMRange(StartLoc, EndLoc)); 1058 } else if (!getSTI().getFeatureBits()[X86::FeatureAVX512]) { 1059 if (X86II::is32ExtendedReg(RegNo)) 1060 return Error(StartLoc, "register %" 1061 + Tok.getString() + " is only available with AVX512", 1062 SMRange(StartLoc, EndLoc)); 1063 } 1064 1065 // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens. 1066 if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) { 1067 RegNo = X86::ST0; 1068 Parser.Lex(); // Eat 'st' 1069 1070 // Check to see if we have '(4)' after %st. 1071 if (getLexer().isNot(AsmToken::LParen)) 1072 return false; 1073 // Lex the paren. 1074 getParser().Lex(); 1075 1076 const AsmToken &IntTok = Parser.getTok(); 1077 if (IntTok.isNot(AsmToken::Integer)) 1078 return Error(IntTok.getLoc(), "expected stack index"); 1079 switch (IntTok.getIntVal()) { 1080 case 0: RegNo = X86::ST0; break; 1081 case 1: RegNo = X86::ST1; break; 1082 case 2: RegNo = X86::ST2; break; 1083 case 3: RegNo = X86::ST3; break; 1084 case 4: RegNo = X86::ST4; break; 1085 case 5: RegNo = X86::ST5; break; 1086 case 6: RegNo = X86::ST6; break; 1087 case 7: RegNo = X86::ST7; break; 1088 default: return Error(IntTok.getLoc(), "invalid stack index"); 1089 } 1090 1091 if (getParser().Lex().isNot(AsmToken::RParen)) 1092 return Error(Parser.getTok().getLoc(), "expected ')'"); 1093 1094 EndLoc = Parser.getTok().getEndLoc(); 1095 Parser.Lex(); // Eat ')' 1096 return false; 1097 } 1098 1099 EndLoc = Parser.getTok().getEndLoc(); 1100 1101 // If this is "db[0-7]", match it as an alias 1102 // for dr[0-7]. 1103 if (RegNo == 0 && Tok.getString().size() == 3 && 1104 Tok.getString().startswith("db")) { 1105 switch (Tok.getString()[2]) { 1106 case '0': RegNo = X86::DR0; break; 1107 case '1': RegNo = X86::DR1; break; 1108 case '2': RegNo = X86::DR2; break; 1109 case '3': RegNo = X86::DR3; break; 1110 case '4': RegNo = X86::DR4; break; 1111 case '5': RegNo = X86::DR5; break; 1112 case '6': RegNo = X86::DR6; break; 1113 case '7': RegNo = X86::DR7; break; 1114 } 1115 1116 if (RegNo != 0) { 1117 EndLoc = Parser.getTok().getEndLoc(); 1118 Parser.Lex(); // Eat it. 1119 return false; 1120 } 1121 } 1122 1123 if (RegNo == 0) { 1124 if (isParsingIntelSyntax()) return true; 1125 return Error(StartLoc, "invalid register name", 1126 SMRange(StartLoc, EndLoc)); 1127 } 1128 1129 Parser.Lex(); // Eat identifier token. 1130 return false; 1131 } 1132 1133 void X86AsmParser::SetFrameRegister(unsigned RegNo) { 1134 Instrumentation->SetInitialFrameRegister(RegNo); 1135 } 1136 1137 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) { 1138 bool Parse32 = is32BitMode() || Code16GCC; 1139 unsigned Basereg = is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI); 1140 const MCExpr *Disp = MCConstantExpr::create(0, getContext()); 1141 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp, 1142 /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1, 1143 Loc, Loc, 0); 1144 } 1145 1146 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) { 1147 bool Parse32 = is32BitMode() || Code16GCC; 1148 unsigned Basereg = is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI); 1149 const MCExpr *Disp = MCConstantExpr::create(0, getContext()); 1150 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp, 1151 /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1, 1152 Loc, Loc, 0); 1153 } 1154 1155 bool X86AsmParser::IsSIReg(unsigned Reg) { 1156 switch (Reg) { 1157 default: llvm_unreachable("Only (R|E)SI and (R|E)DI are expected!"); 1158 case X86::RSI: 1159 case X86::ESI: 1160 case X86::SI: 1161 return true; 1162 case X86::RDI: 1163 case X86::EDI: 1164 case X86::DI: 1165 return false; 1166 } 1167 } 1168 1169 unsigned X86AsmParser::GetSIDIForRegClass(unsigned RegClassID, unsigned Reg, 1170 bool IsSIReg) { 1171 switch (RegClassID) { 1172 default: llvm_unreachable("Unexpected register class"); 1173 case X86::GR64RegClassID: 1174 return IsSIReg ? X86::RSI : X86::RDI; 1175 case X86::GR32RegClassID: 1176 return IsSIReg ? X86::ESI : X86::EDI; 1177 case X86::GR16RegClassID: 1178 return IsSIReg ? X86::SI : X86::DI; 1179 } 1180 } 1181 1182 void X86AsmParser::AddDefaultSrcDestOperands( 1183 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src, 1184 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) { 1185 if (isParsingIntelSyntax()) { 1186 Operands.push_back(std::move(Dst)); 1187 Operands.push_back(std::move(Src)); 1188 } 1189 else { 1190 Operands.push_back(std::move(Src)); 1191 Operands.push_back(std::move(Dst)); 1192 } 1193 } 1194 1195 bool X86AsmParser::VerifyAndAdjustOperands(OperandVector &OrigOperands, 1196 OperandVector &FinalOperands) { 1197 1198 if (OrigOperands.size() > 1) { 1199 // Check if sizes match, OrigOperands also contains the instruction name 1200 assert(OrigOperands.size() == FinalOperands.size() + 1 && 1201 "Operand size mismatch"); 1202 1203 SmallVector<std::pair<SMLoc, std::string>, 2> Warnings; 1204 // Verify types match 1205 int RegClassID = -1; 1206 for (unsigned int i = 0; i < FinalOperands.size(); ++i) { 1207 X86Operand &OrigOp = static_cast<X86Operand &>(*OrigOperands[i + 1]); 1208 X86Operand &FinalOp = static_cast<X86Operand &>(*FinalOperands[i]); 1209 1210 if (FinalOp.isReg() && 1211 (!OrigOp.isReg() || FinalOp.getReg() != OrigOp.getReg())) 1212 // Return false and let a normal complaint about bogus operands happen 1213 return false; 1214 1215 if (FinalOp.isMem()) { 1216 1217 if (!OrigOp.isMem()) 1218 // Return false and let a normal complaint about bogus operands happen 1219 return false; 1220 1221 unsigned OrigReg = OrigOp.Mem.BaseReg; 1222 unsigned FinalReg = FinalOp.Mem.BaseReg; 1223 1224 // If we've already encounterd a register class, make sure all register 1225 // bases are of the same register class 1226 if (RegClassID != -1 && 1227 !X86MCRegisterClasses[RegClassID].contains(OrigReg)) { 1228 return Error(OrigOp.getStartLoc(), 1229 "mismatching source and destination index registers"); 1230 } 1231 1232 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(OrigReg)) 1233 RegClassID = X86::GR64RegClassID; 1234 else if (X86MCRegisterClasses[X86::GR32RegClassID].contains(OrigReg)) 1235 RegClassID = X86::GR32RegClassID; 1236 else if (X86MCRegisterClasses[X86::GR16RegClassID].contains(OrigReg)) 1237 RegClassID = X86::GR16RegClassID; 1238 else 1239 // Unexpected register class type 1240 // Return false and let a normal complaint about bogus operands happen 1241 return false; 1242 1243 bool IsSI = IsSIReg(FinalReg); 1244 FinalReg = GetSIDIForRegClass(RegClassID, FinalReg, IsSI); 1245 1246 if (FinalReg != OrigReg) { 1247 std::string RegName = IsSI ? "ES:(R|E)SI" : "ES:(R|E)DI"; 1248 Warnings.push_back(std::make_pair( 1249 OrigOp.getStartLoc(), 1250 "memory operand is only for determining the size, " + RegName + 1251 " will be used for the location")); 1252 } 1253 1254 FinalOp.Mem.Size = OrigOp.Mem.Size; 1255 FinalOp.Mem.SegReg = OrigOp.Mem.SegReg; 1256 FinalOp.Mem.BaseReg = FinalReg; 1257 } 1258 } 1259 1260 // Produce warnings only if all the operands passed the adjustment - prevent 1261 // legal cases like "movsd (%rax), %xmm0" mistakenly produce warnings 1262 for (auto &WarningMsg : Warnings) { 1263 Warning(WarningMsg.first, WarningMsg.second); 1264 } 1265 1266 // Remove old operands 1267 for (unsigned int i = 0; i < FinalOperands.size(); ++i) 1268 OrigOperands.pop_back(); 1269 } 1270 // OrigOperands.append(FinalOperands.begin(), FinalOperands.end()); 1271 for (unsigned int i = 0; i < FinalOperands.size(); ++i) 1272 OrigOperands.push_back(std::move(FinalOperands[i])); 1273 1274 return false; 1275 } 1276 1277 std::unique_ptr<X86Operand> X86AsmParser::ParseOperand() { 1278 if (isParsingIntelSyntax()) 1279 return ParseIntelOperand(); 1280 return ParseATTOperand(); 1281 } 1282 1283 std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm( 1284 unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg, 1285 unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier, 1286 const InlineAsmIdentifierInfo &Info) { 1287 // If we found a decl other than a VarDecl, then assume it is a FuncDecl or 1288 // some other label reference. 1289 if (Info.isKind(InlineAsmIdentifierInfo::IK_Label)) { 1290 // Insert an explicit size if the user didn't have one. 1291 if (!Size) { 1292 Size = getPointerWidth(); 1293 InstInfo->AsmRewrites->emplace_back(AOK_SizeDirective, Start, 1294 /*Len=*/0, Size); 1295 } 1296 // Create an absolute memory reference in order to match against 1297 // instructions taking a PC relative operand. 1298 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size, 1299 Identifier, Info.Label.Decl); 1300 } 1301 // We either have a direct symbol reference, or an offset from a symbol. The 1302 // parser always puts the symbol on the LHS, so look there for size 1303 // calculation purposes. 1304 unsigned FrontendSize = 0; 1305 void *Decl = nullptr; 1306 bool IsGlobalLV = false; 1307 if (Info.isKind(InlineAsmIdentifierInfo::IK_Var)) { 1308 // Size is in terms of bits in this context. 1309 FrontendSize = Info.Var.Type * 8; 1310 Decl = Info.Var.Decl; 1311 IsGlobalLV = Info.Var.IsGlobalLV; 1312 } 1313 // It is widely common for MS InlineAsm to use a global variable and one/two 1314 // registers in a mmory expression, and though unaccessible via rip/eip. 1315 if (IsGlobalLV && (BaseReg || IndexReg)) { 1316 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End); 1317 // Otherwise, we set the base register to a non-zero value 1318 // if we don't know the actual value at this time. This is necessary to 1319 // get the matching correct in some cases. 1320 } else { 1321 BaseReg = BaseReg ? BaseReg : 1; 1322 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg, 1323 IndexReg, Scale, Start, End, Size, Identifier, 1324 Decl, FrontendSize); 1325 } 1326 } 1327 1328 // Some binary bitwise operators have a named synonymous 1329 // Query a candidate string for being such a named operator 1330 // and if so - invoke the appropriate handler 1331 bool X86AsmParser::ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM) { 1332 // A named operator should be either lower or upper case, but not a mix 1333 if (Name.compare(Name.lower()) && Name.compare(Name.upper())) 1334 return false; 1335 if (Name.equals_lower("not")) 1336 SM.onNot(); 1337 else if (Name.equals_lower("or")) 1338 SM.onOr(); 1339 else if (Name.equals_lower("shl")) 1340 SM.onLShift(); 1341 else if (Name.equals_lower("shr")) 1342 SM.onRShift(); 1343 else if (Name.equals_lower("xor")) 1344 SM.onXor(); 1345 else if (Name.equals_lower("and")) 1346 SM.onAnd(); 1347 else if (Name.equals_lower("mod")) 1348 SM.onMod(); 1349 else 1350 return false; 1351 return true; 1352 } 1353 1354 bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) { 1355 MCAsmParser &Parser = getParser(); 1356 const AsmToken &Tok = Parser.getTok(); 1357 StringRef ErrMsg; 1358 1359 AsmToken::TokenKind PrevTK = AsmToken::Error; 1360 bool Done = false; 1361 while (!Done) { 1362 bool UpdateLocLex = true; 1363 AsmToken::TokenKind TK = getLexer().getKind(); 1364 1365 switch (TK) { 1366 default: 1367 if ((Done = SM.isValidEndState())) 1368 break; 1369 return Error(Tok.getLoc(), "unknown token in expression"); 1370 case AsmToken::EndOfStatement: 1371 Done = true; 1372 break; 1373 case AsmToken::Real: 1374 // DotOperator: [ebx].0 1375 UpdateLocLex = false; 1376 if (ParseIntelDotOperator(SM, End)) 1377 return true; 1378 break; 1379 case AsmToken::String: 1380 case AsmToken::Identifier: { 1381 SMLoc IdentLoc = Tok.getLoc(); 1382 StringRef Identifier = Tok.getString(); 1383 UpdateLocLex = false; 1384 // Register 1385 unsigned Reg; 1386 if (Tok.isNot(AsmToken::String) && !ParseRegister(Reg, IdentLoc, End)) { 1387 if (SM.onRegister(Reg, ErrMsg)) 1388 return Error(Tok.getLoc(), ErrMsg); 1389 break; 1390 } 1391 // Operator synonymous ("not", "or" etc.) 1392 if ((UpdateLocLex = ParseIntelNamedOperator(Identifier, SM))) 1393 break; 1394 // Symbol reference, when parsing assembly content 1395 InlineAsmIdentifierInfo Info; 1396 const MCExpr *Val; 1397 if (!isParsingInlineAsm()) { 1398 if (getParser().parsePrimaryExpr(Val, End)) { 1399 return Error(Tok.getLoc(), "Unexpected identifier!"); 1400 } else if (SM.onIdentifierExpr(Val, Identifier, Info, false, ErrMsg)) { 1401 return Error(IdentLoc, ErrMsg); 1402 } else 1403 break; 1404 } 1405 // MS InlineAsm operators (TYPE/LENGTH/SIZE) 1406 if (unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) { 1407 if (OpKind == IOK_OFFSET) 1408 return Error(IdentLoc, "Dealing OFFSET operator as part of" 1409 "a compound immediate expression is yet to be supported"); 1410 if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) { 1411 if (SM.onInteger(Val, ErrMsg)) 1412 return Error(IdentLoc, ErrMsg); 1413 } else 1414 return true; 1415 break; 1416 } 1417 // MS Dot Operator expression 1418 if (Identifier.count('.') && PrevTK == AsmToken::RBrac) { 1419 if (ParseIntelDotOperator(SM, End)) 1420 return true; 1421 break; 1422 } 1423 // MS InlineAsm identifier 1424 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info, false, End)) 1425 return true; 1426 else if (SM.onIdentifierExpr(Val, Identifier, Info, true, ErrMsg)) 1427 return Error(IdentLoc, ErrMsg); 1428 break; 1429 } 1430 case AsmToken::Integer: { 1431 // Look for 'b' or 'f' following an Integer as a directional label 1432 SMLoc Loc = getTok().getLoc(); 1433 int64_t IntVal = getTok().getIntVal(); 1434 End = consumeToken(); 1435 UpdateLocLex = false; 1436 if (getLexer().getKind() == AsmToken::Identifier) { 1437 StringRef IDVal = getTok().getString(); 1438 if (IDVal == "f" || IDVal == "b") { 1439 MCSymbol *Sym = 1440 getContext().getDirectionalLocalSymbol(IntVal, IDVal == "b"); 1441 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 1442 const MCExpr *Val = 1443 MCSymbolRefExpr::create(Sym, Variant, getContext()); 1444 if (IDVal == "b" && Sym->isUndefined()) 1445 return Error(Loc, "invalid reference to undefined symbol"); 1446 StringRef Identifier = Sym->getName(); 1447 InlineAsmIdentifierInfo Info; 1448 if (SM.onIdentifierExpr(Val, Identifier, Info, 1449 isParsingInlineAsm(), ErrMsg)) 1450 return Error(Loc, ErrMsg); 1451 End = consumeToken(); 1452 } else { 1453 if (SM.onInteger(IntVal, ErrMsg)) 1454 return Error(Loc, ErrMsg); 1455 } 1456 } else { 1457 if (SM.onInteger(IntVal, ErrMsg)) 1458 return Error(Loc, ErrMsg); 1459 } 1460 break; 1461 } 1462 case AsmToken::Plus: 1463 if (SM.onPlus(ErrMsg)) 1464 return Error(getTok().getLoc(), ErrMsg); 1465 break; 1466 case AsmToken::Minus: 1467 if (SM.onMinus(ErrMsg)) 1468 return Error(getTok().getLoc(), ErrMsg); 1469 break; 1470 case AsmToken::Tilde: SM.onNot(); break; 1471 case AsmToken::Star: SM.onStar(); break; 1472 case AsmToken::Slash: SM.onDivide(); break; 1473 case AsmToken::Percent: SM.onMod(); break; 1474 case AsmToken::Pipe: SM.onOr(); break; 1475 case AsmToken::Caret: SM.onXor(); break; 1476 case AsmToken::Amp: SM.onAnd(); break; 1477 case AsmToken::LessLess: 1478 SM.onLShift(); break; 1479 case AsmToken::GreaterGreater: 1480 SM.onRShift(); break; 1481 case AsmToken::LBrac: 1482 if (SM.onLBrac()) 1483 return Error(Tok.getLoc(), "unexpected bracket encountered"); 1484 break; 1485 case AsmToken::RBrac: 1486 if (SM.onRBrac()) 1487 return Error(Tok.getLoc(), "unexpected bracket encountered"); 1488 break; 1489 case AsmToken::LParen: SM.onLParen(); break; 1490 case AsmToken::RParen: SM.onRParen(); break; 1491 } 1492 if (SM.hadError()) 1493 return Error(Tok.getLoc(), "unknown token in expression"); 1494 1495 if (!Done && UpdateLocLex) 1496 End = consumeToken(); 1497 1498 PrevTK = TK; 1499 } 1500 return false; 1501 } 1502 1503 void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &SM, 1504 SMLoc Start, SMLoc End) { 1505 SMLoc Loc = Start; 1506 unsigned ExprLen = End.getPointer() - Start.getPointer(); 1507 // Skip everything before a symbol displacement (if we have one) 1508 if (SM.getSym()) { 1509 StringRef SymName = SM.getSymName(); 1510 if (unsigned Len = SymName.data() - Start.getPointer()) 1511 InstInfo->AsmRewrites->emplace_back(AOK_Skip, Start, Len); 1512 Loc = SMLoc::getFromPointer(SymName.data() + SymName.size()); 1513 ExprLen = End.getPointer() - (SymName.data() + SymName.size()); 1514 // If we have only a symbol than there's no need for complex rewrite, 1515 // simply skip everything after it 1516 if (!(SM.getBaseReg() || SM.getIndexReg() || SM.getImm())) { 1517 if (ExprLen) 1518 InstInfo->AsmRewrites->emplace_back(AOK_Skip, Loc, ExprLen); 1519 return; 1520 } 1521 } 1522 // Build an Intel Expression rewrite 1523 StringRef BaseRegStr; 1524 StringRef IndexRegStr; 1525 if (SM.getBaseReg()) 1526 BaseRegStr = X86IntelInstPrinter::getRegisterName(SM.getBaseReg()); 1527 if (SM.getIndexReg()) 1528 IndexRegStr = X86IntelInstPrinter::getRegisterName(SM.getIndexReg()); 1529 // Emit it 1530 IntelExpr Expr(BaseRegStr, IndexRegStr, SM.getScale(), SM.getImm(), SM.isMemExpr()); 1531 InstInfo->AsmRewrites->emplace_back(Loc, ExprLen, Expr); 1532 } 1533 1534 // Inline assembly may use variable names with namespace alias qualifiers. 1535 bool X86AsmParser::ParseIntelInlineAsmIdentifier(const MCExpr *&Val, 1536 StringRef &Identifier, 1537 InlineAsmIdentifierInfo &Info, 1538 bool IsUnevaluatedOperand, 1539 SMLoc &End) { 1540 MCAsmParser &Parser = getParser(); 1541 assert(isParsingInlineAsm() && "Expected to be parsing inline assembly."); 1542 Val = nullptr; 1543 1544 StringRef LineBuf(Identifier.data()); 1545 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand); 1546 1547 const AsmToken &Tok = Parser.getTok(); 1548 SMLoc Loc = Tok.getLoc(); 1549 1550 // Advance the token stream until the end of the current token is 1551 // after the end of what the frontend claimed. 1552 const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size(); 1553 do { 1554 End = Tok.getEndLoc(); 1555 getLexer().Lex(); 1556 } while (End.getPointer() < EndPtr); 1557 Identifier = LineBuf; 1558 1559 // The frontend should end parsing on an assembler token boundary, unless it 1560 // failed parsing. 1561 assert((End.getPointer() == EndPtr || 1562 Info.isKind(InlineAsmIdentifierInfo::IK_Invalid)) && 1563 "frontend claimed part of a token?"); 1564 1565 // If the identifier lookup was unsuccessful, assume that we are dealing with 1566 // a label. 1567 if (Info.isKind(InlineAsmIdentifierInfo::IK_Invalid)) { 1568 StringRef InternalName = 1569 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(), 1570 Loc, false); 1571 assert(InternalName.size() && "We should have an internal name here."); 1572 // Push a rewrite for replacing the identifier name with the internal name. 1573 InstInfo->AsmRewrites->emplace_back(AOK_Label, Loc, Identifier.size(), 1574 InternalName); 1575 } else if (Info.isKind(InlineAsmIdentifierInfo::IK_EnumVal)) 1576 return false; 1577 // Create the symbol reference. 1578 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 1579 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 1580 Val = MCSymbolRefExpr::create(Sym, Variant, getParser().getContext()); 1581 return false; 1582 } 1583 1584 //ParseRoundingModeOp - Parse AVX-512 rounding mode operand 1585 std::unique_ptr<X86Operand> 1586 X86AsmParser::ParseRoundingModeOp(SMLoc Start, SMLoc End) { 1587 MCAsmParser &Parser = getParser(); 1588 const AsmToken &Tok = Parser.getTok(); 1589 // Eat "{" and mark the current place. 1590 const SMLoc consumedToken = consumeToken(); 1591 if (Tok.getIdentifier().startswith("r")){ 1592 int rndMode = StringSwitch<int>(Tok.getIdentifier()) 1593 .Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT) 1594 .Case("rd", X86::STATIC_ROUNDING::TO_NEG_INF) 1595 .Case("ru", X86::STATIC_ROUNDING::TO_POS_INF) 1596 .Case("rz", X86::STATIC_ROUNDING::TO_ZERO) 1597 .Default(-1); 1598 if (-1 == rndMode) 1599 return ErrorOperand(Tok.getLoc(), "Invalid rounding mode."); 1600 Parser.Lex(); // Eat "r*" of r*-sae 1601 if (!getLexer().is(AsmToken::Minus)) 1602 return ErrorOperand(Tok.getLoc(), "Expected - at this point"); 1603 Parser.Lex(); // Eat "-" 1604 Parser.Lex(); // Eat the sae 1605 if (!getLexer().is(AsmToken::RCurly)) 1606 return ErrorOperand(Tok.getLoc(), "Expected } at this point"); 1607 Parser.Lex(); // Eat "}" 1608 const MCExpr *RndModeOp = 1609 MCConstantExpr::create(rndMode, Parser.getContext()); 1610 return X86Operand::CreateImm(RndModeOp, Start, End); 1611 } 1612 if(Tok.getIdentifier().equals("sae")){ 1613 Parser.Lex(); // Eat the sae 1614 if (!getLexer().is(AsmToken::RCurly)) 1615 return ErrorOperand(Tok.getLoc(), "Expected } at this point"); 1616 Parser.Lex(); // Eat "}" 1617 return X86Operand::CreateToken("{sae}", consumedToken); 1618 } 1619 return ErrorOperand(Tok.getLoc(), "unknown token in expression"); 1620 } 1621 1622 /// Parse the '.' operator. 1623 bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End) { 1624 const AsmToken &Tok = getTok(); 1625 unsigned Offset; 1626 1627 // Drop the optional '.'. 1628 StringRef DotDispStr = Tok.getString(); 1629 if (DotDispStr.startswith(".")) 1630 DotDispStr = DotDispStr.drop_front(1); 1631 1632 // .Imm gets lexed as a real. 1633 if (Tok.is(AsmToken::Real)) { 1634 APInt DotDisp; 1635 DotDispStr.getAsInteger(10, DotDisp); 1636 Offset = DotDisp.getZExtValue(); 1637 } else if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) { 1638 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.'); 1639 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second, 1640 Offset)) 1641 return Error(Tok.getLoc(), "Unable to lookup field reference!"); 1642 } else 1643 return Error(Tok.getLoc(), "Unexpected token type!"); 1644 1645 // Eat the DotExpression and update End 1646 End = SMLoc::getFromPointer(DotDispStr.data()); 1647 const char *DotExprEndLoc = DotDispStr.data() + DotDispStr.size(); 1648 while (Tok.getLoc().getPointer() < DotExprEndLoc) 1649 Lex(); 1650 SM.addImm(Offset); 1651 return false; 1652 } 1653 1654 /// Parse the 'offset' operator. This operator is used to specify the 1655 /// location rather then the content of a variable. 1656 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() { 1657 MCAsmParser &Parser = getParser(); 1658 const AsmToken &Tok = Parser.getTok(); 1659 SMLoc OffsetOfLoc = Tok.getLoc(); 1660 Parser.Lex(); // Eat offset. 1661 1662 const MCExpr *Val; 1663 InlineAsmIdentifierInfo Info; 1664 SMLoc Start = Tok.getLoc(), End; 1665 StringRef Identifier = Tok.getString(); 1666 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info, 1667 /*Unevaluated=*/false, End)) 1668 return nullptr; 1669 1670 void *Decl = nullptr; 1671 // FIXME: MS evaluates "offset <Constant>" to the underlying integral 1672 if (Info.isKind(InlineAsmIdentifierInfo::IK_EnumVal)) 1673 return ErrorOperand(Start, "offset operator cannot yet handle constants"); 1674 else if (Info.isKind(InlineAsmIdentifierInfo::IK_Var)) 1675 Decl = Info.Var.Decl; 1676 // Don't emit the offset operator. 1677 InstInfo->AsmRewrites->emplace_back(AOK_Skip, OffsetOfLoc, 7); 1678 1679 // The offset operator will have an 'r' constraint, thus we need to create 1680 // register operand to ensure proper matching. Just pick a GPR based on 1681 // the size of a pointer. 1682 bool Parse32 = is32BitMode() || Code16GCC; 1683 unsigned RegNo = is64BitMode() ? X86::RBX : (Parse32 ? X86::EBX : X86::BX); 1684 1685 return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true, 1686 OffsetOfLoc, Identifier, Decl); 1687 } 1688 1689 // Query a candidate string for being an Intel assembly operator 1690 // Report back its kind, or IOK_INVALID if does not evaluated as a known one 1691 unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(StringRef Name) { 1692 return StringSwitch<unsigned>(Name) 1693 .Cases("TYPE","type",IOK_TYPE) 1694 .Cases("SIZE","size",IOK_SIZE) 1695 .Cases("LENGTH","length",IOK_LENGTH) 1696 .Cases("OFFSET","offset",IOK_OFFSET) 1697 .Default(IOK_INVALID); 1698 } 1699 1700 /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator 1701 /// returns the number of elements in an array. It returns the value 1 for 1702 /// non-array variables. The SIZE operator returns the size of a C or C++ 1703 /// variable. A variable's size is the product of its LENGTH and TYPE. The 1704 /// TYPE operator returns the size of a C or C++ type or variable. If the 1705 /// variable is an array, TYPE returns the size of a single element. 1706 unsigned X86AsmParser::ParseIntelInlineAsmOperator(unsigned OpKind) { 1707 MCAsmParser &Parser = getParser(); 1708 const AsmToken &Tok = Parser.getTok(); 1709 Parser.Lex(); // Eat operator. 1710 1711 const MCExpr *Val = nullptr; 1712 InlineAsmIdentifierInfo Info; 1713 SMLoc Start = Tok.getLoc(), End; 1714 StringRef Identifier = Tok.getString(); 1715 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info, 1716 /*Unevaluated=*/true, End)) 1717 return 0; 1718 1719 if (!Info.isKind(InlineAsmIdentifierInfo::IK_Var)) { 1720 Error(Start, "unable to lookup expression"); 1721 return 0; 1722 } 1723 1724 unsigned CVal = 0; 1725 switch(OpKind) { 1726 default: llvm_unreachable("Unexpected operand kind!"); 1727 case IOK_LENGTH: CVal = Info.Var.Length; break; 1728 case IOK_SIZE: CVal = Info.Var.Size; break; 1729 case IOK_TYPE: CVal = Info.Var.Type; break; 1730 } 1731 1732 return CVal; 1733 } 1734 1735 bool X86AsmParser::ParseIntelMemoryOperandSize(unsigned &Size) { 1736 Size = StringSwitch<unsigned>(getTok().getString()) 1737 .Cases("BYTE", "byte", 8) 1738 .Cases("WORD", "word", 16) 1739 .Cases("DWORD", "dword", 32) 1740 .Cases("FLOAT", "float", 32) 1741 .Cases("LONG", "long", 32) 1742 .Cases("FWORD", "fword", 48) 1743 .Cases("DOUBLE", "double", 64) 1744 .Cases("QWORD", "qword", 64) 1745 .Cases("MMWORD","mmword", 64) 1746 .Cases("XWORD", "xword", 80) 1747 .Cases("TBYTE", "tbyte", 80) 1748 .Cases("XMMWORD", "xmmword", 128) 1749 .Cases("YMMWORD", "ymmword", 256) 1750 .Cases("ZMMWORD", "zmmword", 512) 1751 .Cases("OPAQUE", "opaque", -1U) // needs to be non-zero, but doesn't matter 1752 .Default(0); 1753 if (Size) { 1754 const AsmToken &Tok = Lex(); // Eat operand size (e.g., byte, word). 1755 if (!(Tok.getString().equals("PTR") || Tok.getString().equals("ptr"))) 1756 return Error(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!"); 1757 Lex(); // Eat ptr. 1758 } 1759 return false; 1760 } 1761 1762 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() { 1763 MCAsmParser &Parser = getParser(); 1764 const AsmToken &Tok = Parser.getTok(); 1765 SMLoc Start, End; 1766 1767 // FIXME: Offset operator 1768 // Should be handled as part of immediate expression, as other operators 1769 // Currently, only supported as a stand-alone operand 1770 if (isParsingInlineAsm()) 1771 if (IdentifyIntelInlineAsmOperator(Tok.getString()) == IOK_OFFSET) 1772 return ParseIntelOffsetOfOperator(); 1773 1774 // Parse optional Size directive. 1775 unsigned Size; 1776 if (ParseIntelMemoryOperandSize(Size)) 1777 return nullptr; 1778 bool PtrInOperand = bool(Size); 1779 1780 Start = Tok.getLoc(); 1781 1782 // Rounding mode operand. 1783 if (getSTI().getFeatureBits()[X86::FeatureAVX512] && 1784 getLexer().is(AsmToken::LCurly)) 1785 return ParseRoundingModeOp(Start, End); 1786 1787 // Register operand. 1788 unsigned RegNo = 0; 1789 if (Tok.is(AsmToken::Identifier) && !ParseRegister(RegNo, Start, End)) { 1790 if (RegNo == X86::RIP) 1791 return ErrorOperand(Start, "rip can only be used as a base register"); 1792 // A Register followed by ':' is considered a segment override 1793 if (Tok.isNot(AsmToken::Colon)) 1794 return !PtrInOperand ? X86Operand::CreateReg(RegNo, Start, End) : 1795 ErrorOperand(Start, "expected memory operand after 'ptr', " 1796 "found register operand instead"); 1797 // An alleged segment override. check if we have a valid segment register 1798 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo)) 1799 return ErrorOperand(Start, "invalid segment register"); 1800 // Eat ':' and update Start location 1801 Start = Lex().getLoc(); 1802 } 1803 1804 // Immediates and Memory 1805 IntelExprStateMachine SM; 1806 if (ParseIntelExpression(SM, End)) 1807 return nullptr; 1808 1809 if (isParsingInlineAsm()) 1810 RewriteIntelExpression(SM, Start, Tok.getLoc()); 1811 1812 int64_t Imm = SM.getImm(); 1813 const MCExpr *Disp = SM.getSym(); 1814 const MCExpr *ImmDisp = MCConstantExpr::create(Imm, getContext()); 1815 if (Disp && Imm) 1816 Disp = MCBinaryExpr::createAdd(Disp, ImmDisp, getContext()); 1817 if (!Disp) 1818 Disp = ImmDisp; 1819 1820 // RegNo != 0 specifies a valid segment register, 1821 // and we are parsing a segment override 1822 if (!SM.isMemExpr() && !RegNo) 1823 return X86Operand::CreateImm(Disp, Start, End); 1824 1825 StringRef ErrMsg; 1826 unsigned BaseReg = SM.getBaseReg(); 1827 unsigned IndexReg = SM.getIndexReg(); 1828 unsigned Scale = SM.getScale(); 1829 1830 if ((BaseReg || IndexReg) && 1831 CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, ErrMsg)) 1832 return ErrorOperand(Start, ErrMsg); 1833 if (isParsingInlineAsm()) 1834 return CreateMemForInlineAsm(RegNo, Disp, BaseReg, IndexReg, 1835 Scale, Start, End, Size, SM.getSymName(), 1836 SM.getIdentifierInfo()); 1837 if (!(BaseReg || IndexReg || RegNo)) 1838 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size); 1839 return X86Operand::CreateMem(getPointerWidth(), RegNo, Disp, 1840 BaseReg, IndexReg, Scale, Start, End, Size); 1841 } 1842 1843 std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() { 1844 MCAsmParser &Parser = getParser(); 1845 switch (getLexer().getKind()) { 1846 default: 1847 // Parse a memory operand with no segment register. 1848 return ParseMemOperand(0, Parser.getTok().getLoc()); 1849 case AsmToken::Percent: { 1850 // Read the register. 1851 unsigned RegNo; 1852 SMLoc Start, End; 1853 if (ParseRegister(RegNo, Start, End)) return nullptr; 1854 if (RegNo == X86::EIZ || RegNo == X86::RIZ) { 1855 Error(Start, "%eiz and %riz can only be used as index registers", 1856 SMRange(Start, End)); 1857 return nullptr; 1858 } 1859 if (RegNo == X86::RIP) { 1860 Error(Start, "%rip can only be used as a base register", 1861 SMRange(Start, End)); 1862 return nullptr; 1863 } 1864 1865 // If this is a segment register followed by a ':', then this is the start 1866 // of a memory reference, otherwise this is a normal register reference. 1867 if (getLexer().isNot(AsmToken::Colon)) 1868 return X86Operand::CreateReg(RegNo, Start, End); 1869 1870 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo)) 1871 return ErrorOperand(Start, "invalid segment register"); 1872 1873 getParser().Lex(); // Eat the colon. 1874 return ParseMemOperand(RegNo, Start); 1875 } 1876 case AsmToken::Dollar: { 1877 // $42 -> immediate. 1878 SMLoc Start = Parser.getTok().getLoc(), End; 1879 Parser.Lex(); 1880 const MCExpr *Val; 1881 if (getParser().parseExpression(Val, End)) 1882 return nullptr; 1883 return X86Operand::CreateImm(Val, Start, End); 1884 } 1885 case AsmToken::LCurly:{ 1886 SMLoc Start = Parser.getTok().getLoc(), End; 1887 if (getSTI().getFeatureBits()[X86::FeatureAVX512]) 1888 return ParseRoundingModeOp(Start, End); 1889 return ErrorOperand(Start, "Unexpected '{' in expression"); 1890 } 1891 } 1892 } 1893 1894 // true on failure, false otherwise 1895 // If no {z} mark was found - Parser doesn't advance 1896 bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z, 1897 const SMLoc &StartLoc) { 1898 MCAsmParser &Parser = getParser(); 1899 // Assuming we are just pass the '{' mark, quering the next token 1900 // Searched for {z}, but none was found. Return false, as no parsing error was 1901 // encountered 1902 if (!(getLexer().is(AsmToken::Identifier) && 1903 (getLexer().getTok().getIdentifier() == "z"))) 1904 return false; 1905 Parser.Lex(); // Eat z 1906 // Query and eat the '}' mark 1907 if (!getLexer().is(AsmToken::RCurly)) 1908 return Error(getLexer().getLoc(), "Expected } at this point"); 1909 Parser.Lex(); // Eat '}' 1910 // Assign Z with the {z} mark opernad 1911 Z = X86Operand::CreateToken("{z}", StartLoc); 1912 return false; 1913 } 1914 1915 // true on failure, false otherwise 1916 bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands, 1917 const MCParsedAsmOperand &Op) { 1918 MCAsmParser &Parser = getParser(); 1919 if(getSTI().getFeatureBits()[X86::FeatureAVX512]) { 1920 if (getLexer().is(AsmToken::LCurly)) { 1921 // Eat "{" and mark the current place. 1922 const SMLoc consumedToken = consumeToken(); 1923 // Distinguish {1to<NUM>} from {%k<NUM>}. 1924 if(getLexer().is(AsmToken::Integer)) { 1925 // Parse memory broadcasting ({1to<NUM>}). 1926 if (getLexer().getTok().getIntVal() != 1) 1927 return TokError("Expected 1to<NUM> at this point"); 1928 Parser.Lex(); // Eat "1" of 1to8 1929 if (!getLexer().is(AsmToken::Identifier) || 1930 !getLexer().getTok().getIdentifier().startswith("to")) 1931 return TokError("Expected 1to<NUM> at this point"); 1932 // Recognize only reasonable suffixes. 1933 const char *BroadcastPrimitive = 1934 StringSwitch<const char*>(getLexer().getTok().getIdentifier()) 1935 .Case("to2", "{1to2}") 1936 .Case("to4", "{1to4}") 1937 .Case("to8", "{1to8}") 1938 .Case("to16", "{1to16}") 1939 .Default(nullptr); 1940 if (!BroadcastPrimitive) 1941 return TokError("Invalid memory broadcast primitive."); 1942 Parser.Lex(); // Eat "toN" of 1toN 1943 if (!getLexer().is(AsmToken::RCurly)) 1944 return TokError("Expected } at this point"); 1945 Parser.Lex(); // Eat "}" 1946 Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive, 1947 consumedToken)); 1948 // No AVX512 specific primitives can pass 1949 // after memory broadcasting, so return. 1950 return false; 1951 } else { 1952 // Parse either {k}{z}, {z}{k}, {k} or {z} 1953 // last one have no meaning, but GCC accepts it 1954 // Currently, we're just pass a '{' mark 1955 std::unique_ptr<X86Operand> Z; 1956 if (ParseZ(Z, consumedToken)) 1957 return true; 1958 // Reaching here means that parsing of the allegadly '{z}' mark yielded 1959 // no errors. 1960 // Query for the need of further parsing for a {%k<NUM>} mark 1961 if (!Z || getLexer().is(AsmToken::LCurly)) { 1962 SMLoc StartLoc = Z ? consumeToken() : consumedToken; 1963 // Parse an op-mask register mark ({%k<NUM>}), which is now to be 1964 // expected 1965 unsigned RegNo; 1966 SMLoc RegLoc; 1967 if (!ParseRegister(RegNo, RegLoc, StartLoc) && 1968 X86MCRegisterClasses[X86::VK1RegClassID].contains(RegNo)) { 1969 if (RegNo == X86::K0) 1970 return Error(RegLoc, "Register k0 can't be used as write mask"); 1971 if (!getLexer().is(AsmToken::RCurly)) 1972 return Error(getLexer().getLoc(), "Expected } at this point"); 1973 Operands.push_back(X86Operand::CreateToken("{", StartLoc)); 1974 Operands.push_back( 1975 X86Operand::CreateReg(RegNo, StartLoc, StartLoc)); 1976 Operands.push_back(X86Operand::CreateToken("}", consumeToken())); 1977 } else 1978 return Error(getLexer().getLoc(), 1979 "Expected an op-mask register at this point"); 1980 // {%k<NUM>} mark is found, inquire for {z} 1981 if (getLexer().is(AsmToken::LCurly) && !Z) { 1982 // Have we've found a parsing error, or found no (expected) {z} mark 1983 // - report an error 1984 if (ParseZ(Z, consumeToken()) || !Z) 1985 return Error(getLexer().getLoc(), 1986 "Expected a {z} mark at this point"); 1987 1988 } 1989 // '{z}' on its own is meaningless, hence should be ignored. 1990 // on the contrary - have it been accompanied by a K register, 1991 // allow it. 1992 if (Z) 1993 Operands.push_back(std::move(Z)); 1994 } 1995 } 1996 } 1997 } 1998 return false; 1999 } 2000 2001 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix 2002 /// has already been parsed if present. 2003 std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg, 2004 SMLoc MemStart) { 2005 2006 MCAsmParser &Parser = getParser(); 2007 // We have to disambiguate a parenthesized expression "(4+5)" from the start 2008 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The 2009 // only way to do this without lookahead is to eat the '(' and see what is 2010 // after it. 2011 const MCExpr *Disp = MCConstantExpr::create(0, getParser().getContext()); 2012 if (getLexer().isNot(AsmToken::LParen)) { 2013 SMLoc ExprEnd; 2014 if (getParser().parseExpression(Disp, ExprEnd)) return nullptr; 2015 2016 // After parsing the base expression we could either have a parenthesized 2017 // memory address or not. If not, return now. If so, eat the (. 2018 if (getLexer().isNot(AsmToken::LParen)) { 2019 // Unless we have a segment register, treat this as an immediate. 2020 if (SegReg == 0) 2021 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, ExprEnd); 2022 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1, 2023 MemStart, ExprEnd); 2024 } 2025 2026 // Eat the '('. 2027 Parser.Lex(); 2028 } else { 2029 // Okay, we have a '('. We don't know if this is an expression or not, but 2030 // so we have to eat the ( to see beyond it. 2031 SMLoc LParenLoc = Parser.getTok().getLoc(); 2032 Parser.Lex(); // Eat the '('. 2033 2034 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) { 2035 // Nothing to do here, fall into the code below with the '(' part of the 2036 // memory operand consumed. 2037 } else { 2038 SMLoc ExprEnd; 2039 getLexer().UnLex(AsmToken(AsmToken::LParen, "(")); 2040 2041 // It must be either an parenthesized expression, or an expression that 2042 // begins from a parenthesized expression, parse it now. Example: (1+2) or 2043 // (1+2)+3 2044 if (getParser().parseExpression(Disp, ExprEnd)) 2045 return nullptr; 2046 2047 // After parsing the base expression we could either have a parenthesized 2048 // memory address or not. If not, return now. If so, eat the (. 2049 if (getLexer().isNot(AsmToken::LParen)) { 2050 // Unless we have a segment register, treat this as an immediate. 2051 if (SegReg == 0) 2052 return X86Operand::CreateMem(getPointerWidth(), Disp, LParenLoc, 2053 ExprEnd); 2054 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1, 2055 MemStart, ExprEnd); 2056 } 2057 2058 // Eat the '('. 2059 Parser.Lex(); 2060 } 2061 } 2062 2063 // If we reached here, then we just ate the ( of the memory operand. Process 2064 // the rest of the memory operand. 2065 unsigned BaseReg = 0, IndexReg = 0, Scale = 1; 2066 SMLoc IndexLoc, BaseLoc; 2067 2068 if (getLexer().is(AsmToken::Percent)) { 2069 SMLoc StartLoc, EndLoc; 2070 BaseLoc = Parser.getTok().getLoc(); 2071 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return nullptr; 2072 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) { 2073 Error(StartLoc, "eiz and riz can only be used as index registers", 2074 SMRange(StartLoc, EndLoc)); 2075 return nullptr; 2076 } 2077 } 2078 2079 if (getLexer().is(AsmToken::Comma)) { 2080 Parser.Lex(); // Eat the comma. 2081 IndexLoc = Parser.getTok().getLoc(); 2082 2083 // Following the comma we should have either an index register, or a scale 2084 // value. We don't support the later form, but we want to parse it 2085 // correctly. 2086 // 2087 // Not that even though it would be completely consistent to support syntax 2088 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this. 2089 if (getLexer().is(AsmToken::Percent)) { 2090 SMLoc L; 2091 if (ParseRegister(IndexReg, L, L)) 2092 return nullptr; 2093 if (BaseReg == X86::RIP) { 2094 Error(IndexLoc, "%rip as base register can not have an index register"); 2095 return nullptr; 2096 } 2097 if (IndexReg == X86::RIP) { 2098 Error(IndexLoc, "%rip is not allowed as an index register"); 2099 return nullptr; 2100 } 2101 2102 if (getLexer().isNot(AsmToken::RParen)) { 2103 // Parse the scale amount: 2104 // ::= ',' [scale-expression] 2105 if (getLexer().isNot(AsmToken::Comma)) { 2106 Error(Parser.getTok().getLoc(), 2107 "expected comma in scale expression"); 2108 return nullptr; 2109 } 2110 Parser.Lex(); // Eat the comma. 2111 2112 if (getLexer().isNot(AsmToken::RParen)) { 2113 SMLoc Loc = Parser.getTok().getLoc(); 2114 2115 int64_t ScaleVal; 2116 if (getParser().parseAbsoluteExpression(ScaleVal)){ 2117 Error(Loc, "expected scale expression"); 2118 return nullptr; 2119 } 2120 2121 // Validate the scale amount. 2122 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) && 2123 ScaleVal != 1) { 2124 Error(Loc, "scale factor in 16-bit address must be 1"); 2125 return nullptr; 2126 } 2127 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && 2128 ScaleVal != 8) { 2129 Error(Loc, "scale factor in address must be 1, 2, 4 or 8"); 2130 return nullptr; 2131 } 2132 Scale = (unsigned)ScaleVal; 2133 } 2134 } 2135 } else if (getLexer().isNot(AsmToken::RParen)) { 2136 // A scale amount without an index is ignored. 2137 // index. 2138 SMLoc Loc = Parser.getTok().getLoc(); 2139 2140 int64_t Value; 2141 if (getParser().parseAbsoluteExpression(Value)) 2142 return nullptr; 2143 2144 if (Value != 1) 2145 Warning(Loc, "scale factor without index register is ignored"); 2146 Scale = 1; 2147 } 2148 } 2149 2150 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too. 2151 if (getLexer().isNot(AsmToken::RParen)) { 2152 Error(Parser.getTok().getLoc(), "unexpected token in memory operand"); 2153 return nullptr; 2154 } 2155 SMLoc MemEnd = Parser.getTok().getEndLoc(); 2156 Parser.Lex(); // Eat the ')'. 2157 2158 // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed, 2159 // and then only in non-64-bit modes. Except for DX, which is a special case 2160 // because an unofficial form of in/out instructions uses it. 2161 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) && 2162 (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP && 2163 BaseReg != X86::SI && BaseReg != X86::DI)) && 2164 BaseReg != X86::DX) { 2165 Error(BaseLoc, "invalid 16-bit base register"); 2166 return nullptr; 2167 } 2168 if (BaseReg == 0 && 2169 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) { 2170 Error(IndexLoc, "16-bit memory operand may not include only index register"); 2171 return nullptr; 2172 } 2173 2174 StringRef ErrMsg; 2175 if (CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, ErrMsg)) { 2176 Error(BaseLoc, ErrMsg); 2177 return nullptr; 2178 } 2179 2180 if (SegReg || BaseReg || IndexReg) 2181 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg, 2182 IndexReg, Scale, MemStart, MemEnd); 2183 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, MemEnd); 2184 } 2185 2186 bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 2187 SMLoc NameLoc, OperandVector &Operands) { 2188 MCAsmParser &Parser = getParser(); 2189 InstInfo = &Info; 2190 StringRef PatchedName = Name; 2191 2192 if ((Name.equals("jmp") || Name.equals("jc") || Name.equals("jz")) && 2193 isParsingIntelSyntax() && isParsingInlineAsm()) { 2194 StringRef NextTok = Parser.getTok().getString(); 2195 if (NextTok == "short") { 2196 SMLoc NameEndLoc = 2197 NameLoc.getFromPointer(NameLoc.getPointer() + Name.size()); 2198 // Eat the short keyword 2199 Parser.Lex(); 2200 // MS ignores the short keyword, it determines the jmp type based 2201 // on the distance of the label 2202 InstInfo->AsmRewrites->emplace_back(AOK_Skip, NameEndLoc, 2203 NextTok.size() + 1); 2204 } 2205 } 2206 2207 // FIXME: Hack to recognize setneb as setne. 2208 if (PatchedName.startswith("set") && PatchedName.endswith("b") && 2209 PatchedName != "setb" && PatchedName != "setnb") 2210 PatchedName = PatchedName.substr(0, Name.size()-1); 2211 2212 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}. 2213 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) && 2214 (PatchedName.endswith("ss") || PatchedName.endswith("sd") || 2215 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) { 2216 bool IsVCMP = PatchedName[0] == 'v'; 2217 unsigned CCIdx = IsVCMP ? 4 : 3; 2218 unsigned ComparisonCode = StringSwitch<unsigned>( 2219 PatchedName.slice(CCIdx, PatchedName.size() - 2)) 2220 .Case("eq", 0x00) 2221 .Case("eq_oq", 0x00) 2222 .Case("lt", 0x01) 2223 .Case("lt_os", 0x01) 2224 .Case("le", 0x02) 2225 .Case("le_os", 0x02) 2226 .Case("unord", 0x03) 2227 .Case("unord_q", 0x03) 2228 .Case("neq", 0x04) 2229 .Case("neq_uq", 0x04) 2230 .Case("nlt", 0x05) 2231 .Case("nlt_us", 0x05) 2232 .Case("nle", 0x06) 2233 .Case("nle_us", 0x06) 2234 .Case("ord", 0x07) 2235 .Case("ord_q", 0x07) 2236 /* AVX only from here */ 2237 .Case("eq_uq", 0x08) 2238 .Case("nge", 0x09) 2239 .Case("nge_us", 0x09) 2240 .Case("ngt", 0x0A) 2241 .Case("ngt_us", 0x0A) 2242 .Case("false", 0x0B) 2243 .Case("false_oq", 0x0B) 2244 .Case("neq_oq", 0x0C) 2245 .Case("ge", 0x0D) 2246 .Case("ge_os", 0x0D) 2247 .Case("gt", 0x0E) 2248 .Case("gt_os", 0x0E) 2249 .Case("true", 0x0F) 2250 .Case("true_uq", 0x0F) 2251 .Case("eq_os", 0x10) 2252 .Case("lt_oq", 0x11) 2253 .Case("le_oq", 0x12) 2254 .Case("unord_s", 0x13) 2255 .Case("neq_us", 0x14) 2256 .Case("nlt_uq", 0x15) 2257 .Case("nle_uq", 0x16) 2258 .Case("ord_s", 0x17) 2259 .Case("eq_us", 0x18) 2260 .Case("nge_uq", 0x19) 2261 .Case("ngt_uq", 0x1A) 2262 .Case("false_os", 0x1B) 2263 .Case("neq_os", 0x1C) 2264 .Case("ge_oq", 0x1D) 2265 .Case("gt_oq", 0x1E) 2266 .Case("true_us", 0x1F) 2267 .Default(~0U); 2268 if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) { 2269 2270 Operands.push_back(X86Operand::CreateToken(PatchedName.slice(0, CCIdx), 2271 NameLoc)); 2272 2273 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode, 2274 getParser().getContext()); 2275 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc)); 2276 2277 PatchedName = PatchedName.substr(PatchedName.size() - 2); 2278 } 2279 } 2280 2281 // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}. 2282 if (PatchedName.startswith("vpcmp") && 2283 (PatchedName.endswith("b") || PatchedName.endswith("w") || 2284 PatchedName.endswith("d") || PatchedName.endswith("q"))) { 2285 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1; 2286 unsigned ComparisonCode = StringSwitch<unsigned>( 2287 PatchedName.slice(5, PatchedName.size() - CCIdx)) 2288 .Case("eq", 0x0) // Only allowed on unsigned. Checked below. 2289 .Case("lt", 0x1) 2290 .Case("le", 0x2) 2291 //.Case("false", 0x3) // Not a documented alias. 2292 .Case("neq", 0x4) 2293 .Case("nlt", 0x5) 2294 .Case("nle", 0x6) 2295 //.Case("true", 0x7) // Not a documented alias. 2296 .Default(~0U); 2297 if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) { 2298 Operands.push_back(X86Operand::CreateToken("vpcmp", NameLoc)); 2299 2300 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode, 2301 getParser().getContext()); 2302 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc)); 2303 2304 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx); 2305 } 2306 } 2307 2308 // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}. 2309 if (PatchedName.startswith("vpcom") && 2310 (PatchedName.endswith("b") || PatchedName.endswith("w") || 2311 PatchedName.endswith("d") || PatchedName.endswith("q"))) { 2312 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1; 2313 unsigned ComparisonCode = StringSwitch<unsigned>( 2314 PatchedName.slice(5, PatchedName.size() - CCIdx)) 2315 .Case("lt", 0x0) 2316 .Case("le", 0x1) 2317 .Case("gt", 0x2) 2318 .Case("ge", 0x3) 2319 .Case("eq", 0x4) 2320 .Case("neq", 0x5) 2321 .Case("false", 0x6) 2322 .Case("true", 0x7) 2323 .Default(~0U); 2324 if (ComparisonCode != ~0U) { 2325 Operands.push_back(X86Operand::CreateToken("vpcom", NameLoc)); 2326 2327 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode, 2328 getParser().getContext()); 2329 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc)); 2330 2331 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx); 2332 } 2333 } 2334 2335 2336 // Determine whether this is an instruction prefix. 2337 // FIXME: 2338 // Enhance prefixes integrity robustness. for example, following forms 2339 // are currently tolerated: 2340 // repz repnz <insn> ; GAS errors for the use of two similar prefixes 2341 // lock addq %rax, %rbx ; Destination operand must be of memory type 2342 // xacquire <insn> ; xacquire must be accompanied by 'lock' 2343 bool isPrefix = StringSwitch<bool>(Name) 2344 .Cases("rex64", "data32", "data16", true) 2345 .Cases("xacquire", "xrelease", true) 2346 .Cases("acquire", "release", isParsingIntelSyntax()) 2347 .Default(false); 2348 2349 auto isLockRepeatPrefix = [](StringRef N) { 2350 return StringSwitch<bool>(N) 2351 .Cases("lock", "rep", "repe", "repz", "repne", "repnz", true) 2352 .Default(false); 2353 }; 2354 2355 bool CurlyAsEndOfStatement = false; 2356 2357 unsigned Flags = X86::IP_NO_PREFIX; 2358 while (isLockRepeatPrefix(Name.lower())) { 2359 unsigned Prefix = 2360 StringSwitch<unsigned>(Name) 2361 .Cases("lock", "lock", X86::IP_HAS_LOCK) 2362 .Cases("rep", "repe", "repz", X86::IP_HAS_REPEAT) 2363 .Cases("repne", "repnz", X86::IP_HAS_REPEAT_NE) 2364 .Default(X86::IP_NO_PREFIX); // Invalid prefix (impossible) 2365 Flags |= Prefix; 2366 Name = Parser.getTok().getString(); 2367 Parser.Lex(); // eat the prefix 2368 // Hack: we could have something like 2369 // "lock; cmpxchg16b $1" or "lock\0A\09incl" or "lock/incl" 2370 while (Name.startswith(";") || Name.startswith("\n") || 2371 Name.startswith("\t") || Name.startswith("/")) { 2372 Name = Parser.getTok().getString(); 2373 Parser.Lex(); // go to next prefix or instr 2374 } 2375 } 2376 2377 if (Flags) 2378 PatchedName = Name; 2379 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc)); 2380 2381 // This does the actual operand parsing. Don't parse any more if we have a 2382 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we 2383 // just want to parse the "lock" as the first instruction and the "incl" as 2384 // the next one. 2385 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) { 2386 // Parse '*' modifier. 2387 if (getLexer().is(AsmToken::Star)) 2388 Operands.push_back(X86Operand::CreateToken("*", consumeToken())); 2389 2390 // Read the operands. 2391 while(1) { 2392 if (std::unique_ptr<X86Operand> Op = ParseOperand()) { 2393 Operands.push_back(std::move(Op)); 2394 if (HandleAVX512Operand(Operands, *Operands.back())) 2395 return true; 2396 } else { 2397 return true; 2398 } 2399 // check for comma and eat it 2400 if (getLexer().is(AsmToken::Comma)) 2401 Parser.Lex(); 2402 else 2403 break; 2404 } 2405 2406 // In MS inline asm curly braces mark the beginning/end of a block, 2407 // therefore they should be interepreted as end of statement 2408 CurlyAsEndOfStatement = 2409 isParsingIntelSyntax() && isParsingInlineAsm() && 2410 (getLexer().is(AsmToken::LCurly) || getLexer().is(AsmToken::RCurly)); 2411 if (getLexer().isNot(AsmToken::EndOfStatement) && !CurlyAsEndOfStatement) 2412 return TokError("unexpected token in argument list"); 2413 } 2414 2415 // Consume the EndOfStatement or the prefix separator Slash 2416 if (getLexer().is(AsmToken::EndOfStatement) || 2417 (isPrefix && getLexer().is(AsmToken::Slash))) 2418 Parser.Lex(); 2419 else if (CurlyAsEndOfStatement) 2420 // Add an actual EndOfStatement before the curly brace 2421 Info.AsmRewrites->emplace_back(AOK_EndOfStatement, 2422 getLexer().getTok().getLoc(), 0); 2423 2424 // This is for gas compatibility and cannot be done in td. 2425 // Adding "p" for some floating point with no argument. 2426 // For example: fsub --> fsubp 2427 bool IsFp = 2428 Name == "fsub" || Name == "fdiv" || Name == "fsubr" || Name == "fdivr"; 2429 if (IsFp && Operands.size() == 1) { 2430 const char *Repl = StringSwitch<const char *>(Name) 2431 .Case("fsub", "fsubp") 2432 .Case("fdiv", "fdivp") 2433 .Case("fsubr", "fsubrp") 2434 .Case("fdivr", "fdivrp"); 2435 static_cast<X86Operand &>(*Operands[0]).setTokenValue(Repl); 2436 } 2437 2438 // Moving a 32 or 16 bit value into a segment register has the same 2439 // behavior. Modify such instructions to always take shorter form. 2440 if ((Name == "mov" || Name == "movw" || Name == "movl") && 2441 (Operands.size() == 3)) { 2442 X86Operand &Op1 = (X86Operand &)*Operands[1]; 2443 X86Operand &Op2 = (X86Operand &)*Operands[2]; 2444 SMLoc Loc = Op1.getEndLoc(); 2445 if (Op1.isReg() && Op2.isReg() && 2446 X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains( 2447 Op2.getReg()) && 2448 (X86MCRegisterClasses[X86::GR16RegClassID].contains(Op1.getReg()) || 2449 X86MCRegisterClasses[X86::GR32RegClassID].contains(Op1.getReg()))) { 2450 // Change instruction name to match new instruction. 2451 if (Name != "mov" && Name[3] == (is16BitMode() ? 'l' : 'w')) { 2452 Name = is16BitMode() ? "movw" : "movl"; 2453 Operands[0] = X86Operand::CreateToken(Name, NameLoc); 2454 } 2455 // Select the correct equivalent 16-/32-bit source register. 2456 unsigned Reg = 2457 getX86SubSuperRegisterOrZero(Op1.getReg(), is16BitMode() ? 16 : 32); 2458 Operands[1] = X86Operand::CreateReg(Reg, Loc, Loc); 2459 } 2460 } 2461 2462 // This is a terrible hack to handle "out[s]?[bwl]? %al, (%dx)" -> 2463 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely 2464 // documented form in various unofficial manuals, so a lot of code uses it. 2465 if ((Name == "outb" || Name == "outsb" || Name == "outw" || Name == "outsw" || 2466 Name == "outl" || Name == "outsl" || Name == "out" || Name == "outs") && 2467 Operands.size() == 3) { 2468 X86Operand &Op = (X86Operand &)*Operands.back(); 2469 if (Op.isMem() && Op.Mem.SegReg == 0 && 2470 isa<MCConstantExpr>(Op.Mem.Disp) && 2471 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 && 2472 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) { 2473 SMLoc Loc = Op.getEndLoc(); 2474 Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc); 2475 } 2476 } 2477 // Same hack for "in[s]?[bwl]? (%dx), %al" -> "inb %dx, %al". 2478 if ((Name == "inb" || Name == "insb" || Name == "inw" || Name == "insw" || 2479 Name == "inl" || Name == "insl" || Name == "in" || Name == "ins") && 2480 Operands.size() == 3) { 2481 X86Operand &Op = (X86Operand &)*Operands[1]; 2482 if (Op.isMem() && Op.Mem.SegReg == 0 && 2483 isa<MCConstantExpr>(Op.Mem.Disp) && 2484 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 && 2485 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) { 2486 SMLoc Loc = Op.getEndLoc(); 2487 Operands[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc); 2488 } 2489 } 2490 2491 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 2> TmpOperands; 2492 bool HadVerifyError = false; 2493 2494 // Append default arguments to "ins[bwld]" 2495 if (Name.startswith("ins") && 2496 (Operands.size() == 1 || Operands.size() == 3) && 2497 (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd" || 2498 Name == "ins")) { 2499 2500 AddDefaultSrcDestOperands(TmpOperands, 2501 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc), 2502 DefaultMemDIOperand(NameLoc)); 2503 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands); 2504 } 2505 2506 // Append default arguments to "outs[bwld]" 2507 if (Name.startswith("outs") && 2508 (Operands.size() == 1 || Operands.size() == 3) && 2509 (Name == "outsb" || Name == "outsw" || Name == "outsl" || 2510 Name == "outsd" || Name == "outs")) { 2511 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc), 2512 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc)); 2513 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands); 2514 } 2515 2516 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate 2517 // values of $SIREG according to the mode. It would be nice if this 2518 // could be achieved with InstAlias in the tables. 2519 if (Name.startswith("lods") && 2520 (Operands.size() == 1 || Operands.size() == 2) && 2521 (Name == "lods" || Name == "lodsb" || Name == "lodsw" || 2522 Name == "lodsl" || Name == "lodsd" || Name == "lodsq")) { 2523 TmpOperands.push_back(DefaultMemSIOperand(NameLoc)); 2524 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands); 2525 } 2526 2527 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate 2528 // values of $DIREG according to the mode. It would be nice if this 2529 // could be achieved with InstAlias in the tables. 2530 if (Name.startswith("stos") && 2531 (Operands.size() == 1 || Operands.size() == 2) && 2532 (Name == "stos" || Name == "stosb" || Name == "stosw" || 2533 Name == "stosl" || Name == "stosd" || Name == "stosq")) { 2534 TmpOperands.push_back(DefaultMemDIOperand(NameLoc)); 2535 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands); 2536 } 2537 2538 // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate 2539 // values of $DIREG according to the mode. It would be nice if this 2540 // could be achieved with InstAlias in the tables. 2541 if (Name.startswith("scas") && 2542 (Operands.size() == 1 || Operands.size() == 2) && 2543 (Name == "scas" || Name == "scasb" || Name == "scasw" || 2544 Name == "scasl" || Name == "scasd" || Name == "scasq")) { 2545 TmpOperands.push_back(DefaultMemDIOperand(NameLoc)); 2546 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands); 2547 } 2548 2549 // Add default SI and DI operands to "cmps[bwlq]". 2550 if (Name.startswith("cmps") && 2551 (Operands.size() == 1 || Operands.size() == 3) && 2552 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" || 2553 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) { 2554 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc), 2555 DefaultMemSIOperand(NameLoc)); 2556 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands); 2557 } 2558 2559 // Add default SI and DI operands to "movs[bwlq]". 2560 if (((Name.startswith("movs") && 2561 (Name == "movs" || Name == "movsb" || Name == "movsw" || 2562 Name == "movsl" || Name == "movsd" || Name == "movsq")) || 2563 (Name.startswith("smov") && 2564 (Name == "smov" || Name == "smovb" || Name == "smovw" || 2565 Name == "smovl" || Name == "smovd" || Name == "smovq"))) && 2566 (Operands.size() == 1 || Operands.size() == 3)) { 2567 if (Name == "movsd" && Operands.size() == 1 && !isParsingIntelSyntax()) 2568 Operands.back() = X86Operand::CreateToken("movsl", NameLoc); 2569 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc), 2570 DefaultMemDIOperand(NameLoc)); 2571 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands); 2572 } 2573 2574 // Check if we encountered an error for one the string insturctions 2575 if (HadVerifyError) { 2576 return HadVerifyError; 2577 } 2578 2579 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to 2580 // "shift <op>". 2581 if ((Name.startswith("shr") || Name.startswith("sar") || 2582 Name.startswith("shl") || Name.startswith("sal") || 2583 Name.startswith("rcl") || Name.startswith("rcr") || 2584 Name.startswith("rol") || Name.startswith("ror")) && 2585 Operands.size() == 3) { 2586 if (isParsingIntelSyntax()) { 2587 // Intel syntax 2588 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]); 2589 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) && 2590 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1) 2591 Operands.pop_back(); 2592 } else { 2593 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]); 2594 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) && 2595 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1) 2596 Operands.erase(Operands.begin() + 1); 2597 } 2598 } 2599 2600 // Transforms "int $3" into "int3" as a size optimization. We can't write an 2601 // instalias with an immediate operand yet. 2602 if (Name == "int" && Operands.size() == 2) { 2603 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]); 2604 if (Op1.isImm()) 2605 if (auto *CE = dyn_cast<MCConstantExpr>(Op1.getImm())) 2606 if (CE->getValue() == 3) { 2607 Operands.erase(Operands.begin() + 1); 2608 static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3"); 2609 } 2610 } 2611 2612 // Transforms "xlat mem8" into "xlatb" 2613 if ((Name == "xlat" || Name == "xlatb") && Operands.size() == 2) { 2614 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]); 2615 if (Op1.isMem8()) { 2616 Warning(Op1.getStartLoc(), "memory operand is only for determining the " 2617 "size, (R|E)BX will be used for the location"); 2618 Operands.pop_back(); 2619 static_cast<X86Operand &>(*Operands[0]).setTokenValue("xlatb"); 2620 } 2621 } 2622 2623 if (Flags) 2624 Operands.push_back(X86Operand::CreatePrefix(Flags, NameLoc, NameLoc)); 2625 return false; 2626 } 2627 2628 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) { 2629 return false; 2630 } 2631 2632 bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) { 2633 const MCRegisterInfo *MRI = getContext().getRegisterInfo(); 2634 2635 switch (Inst.getOpcode()) { 2636 case X86::VGATHERDPDYrm: 2637 case X86::VGATHERDPDrm: 2638 case X86::VGATHERDPSYrm: 2639 case X86::VGATHERDPSrm: 2640 case X86::VGATHERQPDYrm: 2641 case X86::VGATHERQPDrm: 2642 case X86::VGATHERQPSYrm: 2643 case X86::VGATHERQPSrm: 2644 case X86::VPGATHERDDYrm: 2645 case X86::VPGATHERDDrm: 2646 case X86::VPGATHERDQYrm: 2647 case X86::VPGATHERDQrm: 2648 case X86::VPGATHERQDYrm: 2649 case X86::VPGATHERQDrm: 2650 case X86::VPGATHERQQYrm: 2651 case X86::VPGATHERQQrm: { 2652 unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg()); 2653 unsigned Mask = MRI->getEncodingValue(Inst.getOperand(1).getReg()); 2654 unsigned Index = 2655 MRI->getEncodingValue(Inst.getOperand(3 + X86::AddrIndexReg).getReg()); 2656 if (Dest == Mask || Dest == Index || Mask == Index) 2657 return Warning(Ops[0]->getStartLoc(), "mask, index, and destination " 2658 "registers should be distinct"); 2659 break; 2660 } 2661 case X86::VGATHERDPDZ128rm: 2662 case X86::VGATHERDPDZ256rm: 2663 case X86::VGATHERDPDZrm: 2664 case X86::VGATHERDPSZ128rm: 2665 case X86::VGATHERDPSZ256rm: 2666 case X86::VGATHERDPSZrm: 2667 case X86::VGATHERQPDZ128rm: 2668 case X86::VGATHERQPDZ256rm: 2669 case X86::VGATHERQPDZrm: 2670 case X86::VGATHERQPSZ128rm: 2671 case X86::VGATHERQPSZ256rm: 2672 case X86::VGATHERQPSZrm: 2673 case X86::VPGATHERDDZ128rm: 2674 case X86::VPGATHERDDZ256rm: 2675 case X86::VPGATHERDDZrm: 2676 case X86::VPGATHERDQZ128rm: 2677 case X86::VPGATHERDQZ256rm: 2678 case X86::VPGATHERDQZrm: 2679 case X86::VPGATHERQDZ128rm: 2680 case X86::VPGATHERQDZ256rm: 2681 case X86::VPGATHERQDZrm: 2682 case X86::VPGATHERQQZ128rm: 2683 case X86::VPGATHERQQZ256rm: 2684 case X86::VPGATHERQQZrm: { 2685 unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg()); 2686 unsigned Index = 2687 MRI->getEncodingValue(Inst.getOperand(4 + X86::AddrIndexReg).getReg()); 2688 if (Dest == Index) 2689 return Warning(Ops[0]->getStartLoc(), "index and destination registers " 2690 "should be distinct"); 2691 break; 2692 } 2693 } 2694 2695 return false; 2696 } 2697 2698 static const char *getSubtargetFeatureName(uint64_t Val); 2699 2700 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands, 2701 MCStreamer &Out) { 2702 Instrumentation->InstrumentAndEmitInstruction(Inst, Operands, getContext(), 2703 MII, Out); 2704 } 2705 2706 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 2707 OperandVector &Operands, 2708 MCStreamer &Out, uint64_t &ErrorInfo, 2709 bool MatchingInlineAsm) { 2710 if (isParsingIntelSyntax()) 2711 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo, 2712 MatchingInlineAsm); 2713 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo, 2714 MatchingInlineAsm); 2715 } 2716 2717 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, 2718 OperandVector &Operands, MCStreamer &Out, 2719 bool MatchingInlineAsm) { 2720 // FIXME: This should be replaced with a real .td file alias mechanism. 2721 // Also, MatchInstructionImpl should actually *do* the EmitInstruction 2722 // call. 2723 const char *Repl = StringSwitch<const char *>(Op.getToken()) 2724 .Case("finit", "fninit") 2725 .Case("fsave", "fnsave") 2726 .Case("fstcw", "fnstcw") 2727 .Case("fstcww", "fnstcw") 2728 .Case("fstenv", "fnstenv") 2729 .Case("fstsw", "fnstsw") 2730 .Case("fstsww", "fnstsw") 2731 .Case("fclex", "fnclex") 2732 .Default(nullptr); 2733 if (Repl) { 2734 MCInst Inst; 2735 Inst.setOpcode(X86::WAIT); 2736 Inst.setLoc(IDLoc); 2737 if (!MatchingInlineAsm) 2738 EmitInstruction(Inst, Operands, Out); 2739 Operands[0] = X86Operand::CreateToken(Repl, IDLoc); 2740 } 2741 } 2742 2743 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo, 2744 bool MatchingInlineAsm) { 2745 assert(ErrorInfo && "Unknown missing feature!"); 2746 SmallString<126> Msg; 2747 raw_svector_ostream OS(Msg); 2748 OS << "instruction requires:"; 2749 uint64_t Mask = 1; 2750 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) { 2751 if (ErrorInfo & Mask) 2752 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask); 2753 Mask <<= 1; 2754 } 2755 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm); 2756 } 2757 2758 static unsigned getPrefixes(OperandVector &Operands) { 2759 unsigned Result = 0; 2760 X86Operand &Prefix = static_cast<X86Operand &>(*Operands.back()); 2761 if (Prefix.isPrefix()) { 2762 Result = Prefix.getPrefix(); 2763 Operands.pop_back(); 2764 } 2765 return Result; 2766 } 2767 2768 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode, 2769 OperandVector &Operands, 2770 MCStreamer &Out, 2771 uint64_t &ErrorInfo, 2772 bool MatchingInlineAsm) { 2773 assert(!Operands.empty() && "Unexpect empty operand list!"); 2774 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]); 2775 assert(Op.isToken() && "Leading operand should always be a mnemonic!"); 2776 SMRange EmptyRange = None; 2777 2778 // First, handle aliases that expand to multiple instructions. 2779 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm); 2780 2781 bool WasOriginallyInvalidOperand = false; 2782 unsigned Prefixes = getPrefixes(Operands); 2783 2784 MCInst Inst; 2785 2786 if (Prefixes) 2787 Inst.setFlags(Prefixes); 2788 2789 // First, try a direct match. 2790 switch (MatchInstruction(Operands, Inst, ErrorInfo, MatchingInlineAsm, 2791 isParsingIntelSyntax())) { 2792 default: llvm_unreachable("Unexpected match result!"); 2793 case Match_Success: 2794 if (validateInstruction(Inst, Operands)) 2795 return true; 2796 // Some instructions need post-processing to, for example, tweak which 2797 // encoding is selected. Loop on it while changes happen so the 2798 // individual transformations can chain off each other. 2799 if (!MatchingInlineAsm) 2800 while (processInstruction(Inst, Operands)) 2801 ; 2802 2803 Inst.setLoc(IDLoc); 2804 if (!MatchingInlineAsm) 2805 EmitInstruction(Inst, Operands, Out); 2806 Opcode = Inst.getOpcode(); 2807 return false; 2808 case Match_MissingFeature: 2809 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm); 2810 case Match_InvalidOperand: 2811 WasOriginallyInvalidOperand = true; 2812 break; 2813 case Match_MnemonicFail: 2814 break; 2815 } 2816 2817 // FIXME: Ideally, we would only attempt suffix matches for things which are 2818 // valid prefixes, and we could just infer the right unambiguous 2819 // type. However, that requires substantially more matcher support than the 2820 // following hack. 2821 2822 // Change the operand to point to a temporary token. 2823 StringRef Base = Op.getToken(); 2824 SmallString<16> Tmp; 2825 Tmp += Base; 2826 Tmp += ' '; 2827 Op.setTokenValue(Tmp); 2828 2829 // If this instruction starts with an 'f', then it is a floating point stack 2830 // instruction. These come in up to three forms for 32-bit, 64-bit, and 2831 // 80-bit floating point, which use the suffixes s,l,t respectively. 2832 // 2833 // Otherwise, we assume that this may be an integer instruction, which comes 2834 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively. 2835 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0"; 2836 2837 // Check for the various suffix matches. 2838 uint64_t ErrorInfoIgnore; 2839 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings. 2840 unsigned Match[4]; 2841 2842 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) { 2843 Tmp.back() = Suffixes[I]; 2844 Match[I] = MatchInstruction(Operands, Inst, ErrorInfoIgnore, 2845 MatchingInlineAsm, isParsingIntelSyntax()); 2846 // If this returned as a missing feature failure, remember that. 2847 if (Match[I] == Match_MissingFeature) 2848 ErrorInfoMissingFeature = ErrorInfoIgnore; 2849 } 2850 2851 // Restore the old token. 2852 Op.setTokenValue(Base); 2853 2854 // If exactly one matched, then we treat that as a successful match (and the 2855 // instruction will already have been filled in correctly, since the failing 2856 // matches won't have modified it). 2857 unsigned NumSuccessfulMatches = 2858 std::count(std::begin(Match), std::end(Match), Match_Success); 2859 if (NumSuccessfulMatches == 1) { 2860 Inst.setLoc(IDLoc); 2861 if (!MatchingInlineAsm) 2862 EmitInstruction(Inst, Operands, Out); 2863 Opcode = Inst.getOpcode(); 2864 return false; 2865 } 2866 2867 // Otherwise, the match failed, try to produce a decent error message. 2868 2869 // If we had multiple suffix matches, then identify this as an ambiguous 2870 // match. 2871 if (NumSuccessfulMatches > 1) { 2872 char MatchChars[4]; 2873 unsigned NumMatches = 0; 2874 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) 2875 if (Match[I] == Match_Success) 2876 MatchChars[NumMatches++] = Suffixes[I]; 2877 2878 SmallString<126> Msg; 2879 raw_svector_ostream OS(Msg); 2880 OS << "ambiguous instructions require an explicit suffix (could be "; 2881 for (unsigned i = 0; i != NumMatches; ++i) { 2882 if (i != 0) 2883 OS << ", "; 2884 if (i + 1 == NumMatches) 2885 OS << "or "; 2886 OS << "'" << Base << MatchChars[i] << "'"; 2887 } 2888 OS << ")"; 2889 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm); 2890 return true; 2891 } 2892 2893 // Okay, we know that none of the variants matched successfully. 2894 2895 // If all of the instructions reported an invalid mnemonic, then the original 2896 // mnemonic was invalid. 2897 if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) { 2898 if (!WasOriginallyInvalidOperand) { 2899 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'", 2900 Op.getLocRange(), MatchingInlineAsm); 2901 } 2902 2903 // Recover location info for the operand if we know which was the problem. 2904 if (ErrorInfo != ~0ULL) { 2905 if (ErrorInfo >= Operands.size()) 2906 return Error(IDLoc, "too few operands for instruction", EmptyRange, 2907 MatchingInlineAsm); 2908 2909 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo]; 2910 if (Operand.getStartLoc().isValid()) { 2911 SMRange OperandRange = Operand.getLocRange(); 2912 return Error(Operand.getStartLoc(), "invalid operand for instruction", 2913 OperandRange, MatchingInlineAsm); 2914 } 2915 } 2916 2917 return Error(IDLoc, "invalid operand for instruction", EmptyRange, 2918 MatchingInlineAsm); 2919 } 2920 2921 // If one instruction matched with a missing feature, report this as a 2922 // missing feature. 2923 if (std::count(std::begin(Match), std::end(Match), 2924 Match_MissingFeature) == 1) { 2925 ErrorInfo = ErrorInfoMissingFeature; 2926 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature, 2927 MatchingInlineAsm); 2928 } 2929 2930 // If one instruction matched with an invalid operand, report this as an 2931 // operand failure. 2932 if (std::count(std::begin(Match), std::end(Match), 2933 Match_InvalidOperand) == 1) { 2934 return Error(IDLoc, "invalid operand for instruction", EmptyRange, 2935 MatchingInlineAsm); 2936 } 2937 2938 // If all of these were an outright failure, report it in a useless way. 2939 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix", 2940 EmptyRange, MatchingInlineAsm); 2941 return true; 2942 } 2943 2944 bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode, 2945 OperandVector &Operands, 2946 MCStreamer &Out, 2947 uint64_t &ErrorInfo, 2948 bool MatchingInlineAsm) { 2949 assert(!Operands.empty() && "Unexpect empty operand list!"); 2950 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]); 2951 assert(Op.isToken() && "Leading operand should always be a mnemonic!"); 2952 StringRef Mnemonic = Op.getToken(); 2953 SMRange EmptyRange = None; 2954 StringRef Base = Op.getToken(); 2955 unsigned Prefixes = getPrefixes(Operands); 2956 2957 // First, handle aliases that expand to multiple instructions. 2958 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm); 2959 2960 MCInst Inst; 2961 2962 if (Prefixes) 2963 Inst.setFlags(Prefixes); 2964 2965 // Find one unsized memory operand, if present. 2966 X86Operand *UnsizedMemOp = nullptr; 2967 for (const auto &Op : Operands) { 2968 X86Operand *X86Op = static_cast<X86Operand *>(Op.get()); 2969 if (X86Op->isMemUnsized()) { 2970 UnsizedMemOp = X86Op; 2971 // Have we found an unqualified memory operand, 2972 // break. IA allows only one memory operand. 2973 break; 2974 } 2975 } 2976 2977 // Allow some instructions to have implicitly pointer-sized operands. This is 2978 // compatible with gas. 2979 if (UnsizedMemOp) { 2980 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"}; 2981 for (const char *Instr : PtrSizedInstrs) { 2982 if (Mnemonic == Instr) { 2983 UnsizedMemOp->Mem.Size = getPointerWidth(); 2984 break; 2985 } 2986 } 2987 } 2988 2989 SmallVector<unsigned, 8> Match; 2990 uint64_t ErrorInfoMissingFeature = 0; 2991 2992 // If unsized push has immediate operand we should default the default pointer 2993 // size for the size. 2994 if (Mnemonic == "push" && Operands.size() == 2) { 2995 auto *X86Op = static_cast<X86Operand *>(Operands[1].get()); 2996 if (X86Op->isImm()) { 2997 // If it's not a constant fall through and let remainder take care of it. 2998 const auto *CE = dyn_cast<MCConstantExpr>(X86Op->getImm()); 2999 unsigned Size = getPointerWidth(); 3000 if (CE && 3001 (isIntN(Size, CE->getValue()) || isUIntN(Size, CE->getValue()))) { 3002 SmallString<16> Tmp; 3003 Tmp += Base; 3004 Tmp += (is64BitMode()) 3005 ? "q" 3006 : (is32BitMode()) ? "l" : (is16BitMode()) ? "w" : " "; 3007 Op.setTokenValue(Tmp); 3008 // Do match in ATT mode to allow explicit suffix usage. 3009 Match.push_back(MatchInstruction(Operands, Inst, ErrorInfo, 3010 MatchingInlineAsm, 3011 false /*isParsingIntelSyntax()*/)); 3012 Op.setTokenValue(Base); 3013 } 3014 } 3015 } 3016 3017 // If an unsized memory operand is present, try to match with each memory 3018 // operand size. In Intel assembly, the size is not part of the instruction 3019 // mnemonic. 3020 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) { 3021 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512}; 3022 for (unsigned Size : MopSizes) { 3023 UnsizedMemOp->Mem.Size = Size; 3024 uint64_t ErrorInfoIgnore; 3025 unsigned LastOpcode = Inst.getOpcode(); 3026 unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore, 3027 MatchingInlineAsm, isParsingIntelSyntax()); 3028 if (Match.empty() || LastOpcode != Inst.getOpcode()) 3029 Match.push_back(M); 3030 3031 // If this returned as a missing feature failure, remember that. 3032 if (Match.back() == Match_MissingFeature) 3033 ErrorInfoMissingFeature = ErrorInfoIgnore; 3034 } 3035 3036 // Restore the size of the unsized memory operand if we modified it. 3037 UnsizedMemOp->Mem.Size = 0; 3038 } 3039 3040 // If we haven't matched anything yet, this is not a basic integer or FPU 3041 // operation. There shouldn't be any ambiguity in our mnemonic table, so try 3042 // matching with the unsized operand. 3043 if (Match.empty()) { 3044 Match.push_back(MatchInstruction( 3045 Operands, Inst, ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax())); 3046 // If this returned as a missing feature failure, remember that. 3047 if (Match.back() == Match_MissingFeature) 3048 ErrorInfoMissingFeature = ErrorInfo; 3049 } 3050 3051 // Restore the size of the unsized memory operand if we modified it. 3052 if (UnsizedMemOp) 3053 UnsizedMemOp->Mem.Size = 0; 3054 3055 // If it's a bad mnemonic, all results will be the same. 3056 if (Match.back() == Match_MnemonicFail) { 3057 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'", 3058 Op.getLocRange(), MatchingInlineAsm); 3059 } 3060 3061 unsigned NumSuccessfulMatches = 3062 std::count(std::begin(Match), std::end(Match), Match_Success); 3063 3064 // If matching was ambiguous and we had size information from the frontend, 3065 // try again with that. This handles cases like "movxz eax, m8/m16". 3066 if (UnsizedMemOp && NumSuccessfulMatches > 1 && 3067 UnsizedMemOp->getMemFrontendSize()) { 3068 UnsizedMemOp->Mem.Size = UnsizedMemOp->getMemFrontendSize(); 3069 unsigned M = MatchInstruction( 3070 Operands, Inst, ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax()); 3071 if (M == Match_Success) 3072 NumSuccessfulMatches = 1; 3073 3074 // Add a rewrite that encodes the size information we used from the 3075 // frontend. 3076 InstInfo->AsmRewrites->emplace_back( 3077 AOK_SizeDirective, UnsizedMemOp->getStartLoc(), 3078 /*Len=*/0, UnsizedMemOp->getMemFrontendSize()); 3079 } 3080 3081 // If exactly one matched, then we treat that as a successful match (and the 3082 // instruction will already have been filled in correctly, since the failing 3083 // matches won't have modified it). 3084 if (NumSuccessfulMatches == 1) { 3085 if (validateInstruction(Inst, Operands)) 3086 return true; 3087 // Some instructions need post-processing to, for example, tweak which 3088 // encoding is selected. Loop on it while changes happen so the individual 3089 // transformations can chain off each other. 3090 if (!MatchingInlineAsm) 3091 while (processInstruction(Inst, Operands)) 3092 ; 3093 Inst.setLoc(IDLoc); 3094 if (!MatchingInlineAsm) 3095 EmitInstruction(Inst, Operands, Out); 3096 Opcode = Inst.getOpcode(); 3097 return false; 3098 } else if (NumSuccessfulMatches > 1) { 3099 assert(UnsizedMemOp && 3100 "multiple matches only possible with unsized memory operands"); 3101 return Error(UnsizedMemOp->getStartLoc(), 3102 "ambiguous operand size for instruction '" + Mnemonic + "\'", 3103 UnsizedMemOp->getLocRange()); 3104 } 3105 3106 // If one instruction matched with a missing feature, report this as a 3107 // missing feature. 3108 if (std::count(std::begin(Match), std::end(Match), 3109 Match_MissingFeature) == 1) { 3110 ErrorInfo = ErrorInfoMissingFeature; 3111 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature, 3112 MatchingInlineAsm); 3113 } 3114 3115 // If one instruction matched with an invalid operand, report this as an 3116 // operand failure. 3117 if (std::count(std::begin(Match), std::end(Match), 3118 Match_InvalidOperand) == 1) { 3119 return Error(IDLoc, "invalid operand for instruction", EmptyRange, 3120 MatchingInlineAsm); 3121 } 3122 3123 // If all of these were an outright failure, report it in a useless way. 3124 return Error(IDLoc, "unknown instruction mnemonic", EmptyRange, 3125 MatchingInlineAsm); 3126 } 3127 3128 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) { 3129 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo); 3130 } 3131 3132 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) { 3133 MCAsmParser &Parser = getParser(); 3134 StringRef IDVal = DirectiveID.getIdentifier(); 3135 if (IDVal == ".word") 3136 return ParseDirectiveWord(2, DirectiveID.getLoc()); 3137 else if (IDVal.startswith(".code")) 3138 return ParseDirectiveCode(IDVal, DirectiveID.getLoc()); 3139 else if (IDVal.startswith(".att_syntax")) { 3140 getParser().setParsingInlineAsm(false); 3141 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3142 if (Parser.getTok().getString() == "prefix") 3143 Parser.Lex(); 3144 else if (Parser.getTok().getString() == "noprefix") 3145 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not " 3146 "supported: registers must have a " 3147 "'%' prefix in .att_syntax"); 3148 } 3149 getParser().setAssemblerDialect(0); 3150 return false; 3151 } else if (IDVal.startswith(".intel_syntax")) { 3152 getParser().setAssemblerDialect(1); 3153 getParser().setParsingInlineAsm(true); 3154 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3155 if (Parser.getTok().getString() == "noprefix") 3156 Parser.Lex(); 3157 else if (Parser.getTok().getString() == "prefix") 3158 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not " 3159 "supported: registers must not have " 3160 "a '%' prefix in .intel_syntax"); 3161 } 3162 return false; 3163 } else if (IDVal == ".even") 3164 return parseDirectiveEven(DirectiveID.getLoc()); 3165 else if (IDVal == ".cv_fpo_proc") 3166 return parseDirectiveFPOProc(DirectiveID.getLoc()); 3167 else if (IDVal == ".cv_fpo_setframe") 3168 return parseDirectiveFPOSetFrame(DirectiveID.getLoc()); 3169 else if (IDVal == ".cv_fpo_pushreg") 3170 return parseDirectiveFPOPushReg(DirectiveID.getLoc()); 3171 else if (IDVal == ".cv_fpo_stackalloc") 3172 return parseDirectiveFPOStackAlloc(DirectiveID.getLoc()); 3173 else if (IDVal == ".cv_fpo_endprologue") 3174 return parseDirectiveFPOEndPrologue(DirectiveID.getLoc()); 3175 else if (IDVal == ".cv_fpo_endproc") 3176 return parseDirectiveFPOEndProc(DirectiveID.getLoc()); 3177 3178 return true; 3179 } 3180 3181 /// parseDirectiveEven 3182 /// ::= .even 3183 bool X86AsmParser::parseDirectiveEven(SMLoc L) { 3184 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3185 TokError("unexpected token in directive"); 3186 return false; 3187 } 3188 const MCSection *Section = getStreamer().getCurrentSectionOnly(); 3189 if (!Section) { 3190 getStreamer().InitSections(false); 3191 Section = getStreamer().getCurrentSectionOnly(); 3192 } 3193 if (Section->UseCodeAlign()) 3194 getStreamer().EmitCodeAlignment(2, 0); 3195 else 3196 getStreamer().EmitValueToAlignment(2, 0, 1, 0); 3197 return false; 3198 } 3199 /// ParseDirectiveWord 3200 /// ::= .word [ expression (, expression)* ] 3201 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 3202 MCAsmParser &Parser = getParser(); 3203 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3204 for (;;) { 3205 const MCExpr *Value; 3206 SMLoc ExprLoc = getLexer().getLoc(); 3207 if (getParser().parseExpression(Value)) 3208 return false; 3209 3210 if (const auto *MCE = dyn_cast<MCConstantExpr>(Value)) { 3211 assert(Size <= 8 && "Invalid size"); 3212 uint64_t IntValue = MCE->getValue(); 3213 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue)) 3214 return Error(ExprLoc, "literal value out of range for directive"); 3215 getStreamer().EmitIntValue(IntValue, Size); 3216 } else { 3217 getStreamer().EmitValue(Value, Size, ExprLoc); 3218 } 3219 3220 if (getLexer().is(AsmToken::EndOfStatement)) 3221 break; 3222 3223 // FIXME: Improve diagnostic. 3224 if (getLexer().isNot(AsmToken::Comma)) { 3225 Error(L, "unexpected token in directive"); 3226 return false; 3227 } 3228 Parser.Lex(); 3229 } 3230 } 3231 3232 Parser.Lex(); 3233 return false; 3234 } 3235 3236 /// ParseDirectiveCode 3237 /// ::= .code16 | .code32 | .code64 3238 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) { 3239 MCAsmParser &Parser = getParser(); 3240 Code16GCC = false; 3241 if (IDVal == ".code16") { 3242 Parser.Lex(); 3243 if (!is16BitMode()) { 3244 SwitchMode(X86::Mode16Bit); 3245 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 3246 } 3247 } else if (IDVal == ".code16gcc") { 3248 // .code16gcc parses as if in 32-bit mode, but emits code in 16-bit mode. 3249 Parser.Lex(); 3250 Code16GCC = true; 3251 if (!is16BitMode()) { 3252 SwitchMode(X86::Mode16Bit); 3253 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 3254 } 3255 } else if (IDVal == ".code32") { 3256 Parser.Lex(); 3257 if (!is32BitMode()) { 3258 SwitchMode(X86::Mode32Bit); 3259 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 3260 } 3261 } else if (IDVal == ".code64") { 3262 Parser.Lex(); 3263 if (!is64BitMode()) { 3264 SwitchMode(X86::Mode64Bit); 3265 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64); 3266 } 3267 } else { 3268 Error(L, "unknown directive " + IDVal); 3269 return false; 3270 } 3271 3272 return false; 3273 } 3274 3275 // .cv_fpo_proc foo 3276 bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) { 3277 MCAsmParser &Parser = getParser(); 3278 StringRef ProcName; 3279 int64_t ParamsSize; 3280 if (Parser.parseIdentifier(ProcName)) 3281 return Parser.TokError("expected symbol name"); 3282 if (Parser.parseIntToken(ParamsSize, "expected parameter byte count")) 3283 return true; 3284 if (!isUIntN(32, ParamsSize)) 3285 return Parser.TokError("parameters size out of range"); 3286 if (Parser.parseEOL("unexpected tokens")) 3287 return addErrorSuffix(" in '.cv_fpo_proc' directive"); 3288 MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName); 3289 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L); 3290 } 3291 3292 // .cv_fpo_setframe ebp 3293 bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) { 3294 MCAsmParser &Parser = getParser(); 3295 unsigned Reg; 3296 SMLoc DummyLoc; 3297 if (ParseRegister(Reg, DummyLoc, DummyLoc) || 3298 Parser.parseEOL("unexpected tokens")) 3299 return addErrorSuffix(" in '.cv_fpo_setframe' directive"); 3300 return getTargetStreamer().emitFPOSetFrame(Reg, L); 3301 } 3302 3303 // .cv_fpo_pushreg ebx 3304 bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) { 3305 MCAsmParser &Parser = getParser(); 3306 unsigned Reg; 3307 SMLoc DummyLoc; 3308 if (ParseRegister(Reg, DummyLoc, DummyLoc) || 3309 Parser.parseEOL("unexpected tokens")) 3310 return addErrorSuffix(" in '.cv_fpo_pushreg' directive"); 3311 return getTargetStreamer().emitFPOPushReg(Reg, L); 3312 } 3313 3314 // .cv_fpo_stackalloc 20 3315 bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) { 3316 MCAsmParser &Parser = getParser(); 3317 int64_t Offset; 3318 if (Parser.parseIntToken(Offset, "expected offset") || 3319 Parser.parseEOL("unexpected tokens")) 3320 return addErrorSuffix(" in '.cv_fpo_stackalloc' directive"); 3321 return getTargetStreamer().emitFPOStackAlloc(Offset, L); 3322 } 3323 3324 // .cv_fpo_endprologue 3325 bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) { 3326 MCAsmParser &Parser = getParser(); 3327 if (Parser.parseEOL("unexpected tokens")) 3328 return addErrorSuffix(" in '.cv_fpo_endprologue' directive"); 3329 return getTargetStreamer().emitFPOEndPrologue(L); 3330 } 3331 3332 // .cv_fpo_endproc 3333 bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) { 3334 MCAsmParser &Parser = getParser(); 3335 if (Parser.parseEOL("unexpected tokens")) 3336 return addErrorSuffix(" in '.cv_fpo_endproc' directive"); 3337 return getTargetStreamer().emitFPOEndProc(L); 3338 } 3339 3340 // Force static initialization. 3341 extern "C" void LLVMInitializeX86AsmParser() { 3342 RegisterMCAsmParser<X86AsmParser> X(getTheX86_32Target()); 3343 RegisterMCAsmParser<X86AsmParser> Y(getTheX86_64Target()); 3344 } 3345 3346 #define GET_REGISTER_MATCHER 3347 #define GET_MATCHER_IMPLEMENTATION 3348 #define GET_SUBTARGET_FEATURE_NAME 3349 #include "X86GenAsmMatcher.inc" 3350