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-15]", match it as an alias 1102 // for dr[0-15]. 1103 if (RegNo == 0 && Tok.getString().startswith("db")) { 1104 if (Tok.getString().size() == 3) { 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 case '8': RegNo = X86::DR8; break; 1115 case '9': RegNo = X86::DR9; break; 1116 } 1117 } else if (Tok.getString().size() == 4 && Tok.getString()[2] == '1') { 1118 switch (Tok.getString()[3]) { 1119 case '0': RegNo = X86::DR10; break; 1120 case '1': RegNo = X86::DR11; break; 1121 case '2': RegNo = X86::DR12; break; 1122 case '3': RegNo = X86::DR13; break; 1123 case '4': RegNo = X86::DR14; break; 1124 case '5': RegNo = X86::DR15; break; 1125 } 1126 } 1127 1128 if (RegNo != 0) { 1129 EndLoc = Parser.getTok().getEndLoc(); 1130 Parser.Lex(); // Eat it. 1131 return false; 1132 } 1133 } 1134 1135 if (RegNo == 0) { 1136 if (isParsingIntelSyntax()) return true; 1137 return Error(StartLoc, "invalid register name", 1138 SMRange(StartLoc, EndLoc)); 1139 } 1140 1141 Parser.Lex(); // Eat identifier token. 1142 return false; 1143 } 1144 1145 void X86AsmParser::SetFrameRegister(unsigned RegNo) { 1146 Instrumentation->SetInitialFrameRegister(RegNo); 1147 } 1148 1149 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) { 1150 bool Parse32 = is32BitMode() || Code16GCC; 1151 unsigned Basereg = is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI); 1152 const MCExpr *Disp = MCConstantExpr::create(0, getContext()); 1153 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp, 1154 /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1, 1155 Loc, Loc, 0); 1156 } 1157 1158 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) { 1159 bool Parse32 = is32BitMode() || Code16GCC; 1160 unsigned Basereg = is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI); 1161 const MCExpr *Disp = MCConstantExpr::create(0, getContext()); 1162 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp, 1163 /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1, 1164 Loc, Loc, 0); 1165 } 1166 1167 bool X86AsmParser::IsSIReg(unsigned Reg) { 1168 switch (Reg) { 1169 default: llvm_unreachable("Only (R|E)SI and (R|E)DI are expected!"); 1170 case X86::RSI: 1171 case X86::ESI: 1172 case X86::SI: 1173 return true; 1174 case X86::RDI: 1175 case X86::EDI: 1176 case X86::DI: 1177 return false; 1178 } 1179 } 1180 1181 unsigned X86AsmParser::GetSIDIForRegClass(unsigned RegClassID, unsigned Reg, 1182 bool IsSIReg) { 1183 switch (RegClassID) { 1184 default: llvm_unreachable("Unexpected register class"); 1185 case X86::GR64RegClassID: 1186 return IsSIReg ? X86::RSI : X86::RDI; 1187 case X86::GR32RegClassID: 1188 return IsSIReg ? X86::ESI : X86::EDI; 1189 case X86::GR16RegClassID: 1190 return IsSIReg ? X86::SI : X86::DI; 1191 } 1192 } 1193 1194 void X86AsmParser::AddDefaultSrcDestOperands( 1195 OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src, 1196 std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) { 1197 if (isParsingIntelSyntax()) { 1198 Operands.push_back(std::move(Dst)); 1199 Operands.push_back(std::move(Src)); 1200 } 1201 else { 1202 Operands.push_back(std::move(Src)); 1203 Operands.push_back(std::move(Dst)); 1204 } 1205 } 1206 1207 bool X86AsmParser::VerifyAndAdjustOperands(OperandVector &OrigOperands, 1208 OperandVector &FinalOperands) { 1209 1210 if (OrigOperands.size() > 1) { 1211 // Check if sizes match, OrigOperands also contains the instruction name 1212 assert(OrigOperands.size() == FinalOperands.size() + 1 && 1213 "Operand size mismatch"); 1214 1215 SmallVector<std::pair<SMLoc, std::string>, 2> Warnings; 1216 // Verify types match 1217 int RegClassID = -1; 1218 for (unsigned int i = 0; i < FinalOperands.size(); ++i) { 1219 X86Operand &OrigOp = static_cast<X86Operand &>(*OrigOperands[i + 1]); 1220 X86Operand &FinalOp = static_cast<X86Operand &>(*FinalOperands[i]); 1221 1222 if (FinalOp.isReg() && 1223 (!OrigOp.isReg() || FinalOp.getReg() != OrigOp.getReg())) 1224 // Return false and let a normal complaint about bogus operands happen 1225 return false; 1226 1227 if (FinalOp.isMem()) { 1228 1229 if (!OrigOp.isMem()) 1230 // Return false and let a normal complaint about bogus operands happen 1231 return false; 1232 1233 unsigned OrigReg = OrigOp.Mem.BaseReg; 1234 unsigned FinalReg = FinalOp.Mem.BaseReg; 1235 1236 // If we've already encounterd a register class, make sure all register 1237 // bases are of the same register class 1238 if (RegClassID != -1 && 1239 !X86MCRegisterClasses[RegClassID].contains(OrigReg)) { 1240 return Error(OrigOp.getStartLoc(), 1241 "mismatching source and destination index registers"); 1242 } 1243 1244 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(OrigReg)) 1245 RegClassID = X86::GR64RegClassID; 1246 else if (X86MCRegisterClasses[X86::GR32RegClassID].contains(OrigReg)) 1247 RegClassID = X86::GR32RegClassID; 1248 else if (X86MCRegisterClasses[X86::GR16RegClassID].contains(OrigReg)) 1249 RegClassID = X86::GR16RegClassID; 1250 else 1251 // Unexpected register class type 1252 // Return false and let a normal complaint about bogus operands happen 1253 return false; 1254 1255 bool IsSI = IsSIReg(FinalReg); 1256 FinalReg = GetSIDIForRegClass(RegClassID, FinalReg, IsSI); 1257 1258 if (FinalReg != OrigReg) { 1259 std::string RegName = IsSI ? "ES:(R|E)SI" : "ES:(R|E)DI"; 1260 Warnings.push_back(std::make_pair( 1261 OrigOp.getStartLoc(), 1262 "memory operand is only for determining the size, " + RegName + 1263 " will be used for the location")); 1264 } 1265 1266 FinalOp.Mem.Size = OrigOp.Mem.Size; 1267 FinalOp.Mem.SegReg = OrigOp.Mem.SegReg; 1268 FinalOp.Mem.BaseReg = FinalReg; 1269 } 1270 } 1271 1272 // Produce warnings only if all the operands passed the adjustment - prevent 1273 // legal cases like "movsd (%rax), %xmm0" mistakenly produce warnings 1274 for (auto &WarningMsg : Warnings) { 1275 Warning(WarningMsg.first, WarningMsg.second); 1276 } 1277 1278 // Remove old operands 1279 for (unsigned int i = 0; i < FinalOperands.size(); ++i) 1280 OrigOperands.pop_back(); 1281 } 1282 // OrigOperands.append(FinalOperands.begin(), FinalOperands.end()); 1283 for (unsigned int i = 0; i < FinalOperands.size(); ++i) 1284 OrigOperands.push_back(std::move(FinalOperands[i])); 1285 1286 return false; 1287 } 1288 1289 std::unique_ptr<X86Operand> X86AsmParser::ParseOperand() { 1290 if (isParsingIntelSyntax()) 1291 return ParseIntelOperand(); 1292 return ParseATTOperand(); 1293 } 1294 1295 std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm( 1296 unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg, 1297 unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier, 1298 const InlineAsmIdentifierInfo &Info) { 1299 // If we found a decl other than a VarDecl, then assume it is a FuncDecl or 1300 // some other label reference. 1301 if (Info.isKind(InlineAsmIdentifierInfo::IK_Label)) { 1302 // Insert an explicit size if the user didn't have one. 1303 if (!Size) { 1304 Size = getPointerWidth(); 1305 InstInfo->AsmRewrites->emplace_back(AOK_SizeDirective, Start, 1306 /*Len=*/0, Size); 1307 } 1308 // Create an absolute memory reference in order to match against 1309 // instructions taking a PC relative operand. 1310 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size, 1311 Identifier, Info.Label.Decl); 1312 } 1313 // We either have a direct symbol reference, or an offset from a symbol. The 1314 // parser always puts the symbol on the LHS, so look there for size 1315 // calculation purposes. 1316 unsigned FrontendSize = 0; 1317 void *Decl = nullptr; 1318 bool IsGlobalLV = false; 1319 if (Info.isKind(InlineAsmIdentifierInfo::IK_Var)) { 1320 // Size is in terms of bits in this context. 1321 FrontendSize = Info.Var.Type * 8; 1322 Decl = Info.Var.Decl; 1323 IsGlobalLV = Info.Var.IsGlobalLV; 1324 } 1325 // It is widely common for MS InlineAsm to use a global variable and one/two 1326 // registers in a mmory expression, and though unaccessible via rip/eip. 1327 if (IsGlobalLV && (BaseReg || IndexReg)) { 1328 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End); 1329 // Otherwise, we set the base register to a non-zero value 1330 // if we don't know the actual value at this time. This is necessary to 1331 // get the matching correct in some cases. 1332 } else { 1333 BaseReg = BaseReg ? BaseReg : 1; 1334 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg, 1335 IndexReg, Scale, Start, End, Size, Identifier, 1336 Decl, FrontendSize); 1337 } 1338 } 1339 1340 // Some binary bitwise operators have a named synonymous 1341 // Query a candidate string for being such a named operator 1342 // and if so - invoke the appropriate handler 1343 bool X86AsmParser::ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM) { 1344 // A named operator should be either lower or upper case, but not a mix 1345 if (Name.compare(Name.lower()) && Name.compare(Name.upper())) 1346 return false; 1347 if (Name.equals_lower("not")) 1348 SM.onNot(); 1349 else if (Name.equals_lower("or")) 1350 SM.onOr(); 1351 else if (Name.equals_lower("shl")) 1352 SM.onLShift(); 1353 else if (Name.equals_lower("shr")) 1354 SM.onRShift(); 1355 else if (Name.equals_lower("xor")) 1356 SM.onXor(); 1357 else if (Name.equals_lower("and")) 1358 SM.onAnd(); 1359 else if (Name.equals_lower("mod")) 1360 SM.onMod(); 1361 else 1362 return false; 1363 return true; 1364 } 1365 1366 bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) { 1367 MCAsmParser &Parser = getParser(); 1368 const AsmToken &Tok = Parser.getTok(); 1369 StringRef ErrMsg; 1370 1371 AsmToken::TokenKind PrevTK = AsmToken::Error; 1372 bool Done = false; 1373 while (!Done) { 1374 bool UpdateLocLex = true; 1375 AsmToken::TokenKind TK = getLexer().getKind(); 1376 1377 switch (TK) { 1378 default: 1379 if ((Done = SM.isValidEndState())) 1380 break; 1381 return Error(Tok.getLoc(), "unknown token in expression"); 1382 case AsmToken::EndOfStatement: 1383 Done = true; 1384 break; 1385 case AsmToken::Real: 1386 // DotOperator: [ebx].0 1387 UpdateLocLex = false; 1388 if (ParseIntelDotOperator(SM, End)) 1389 return true; 1390 break; 1391 case AsmToken::String: 1392 case AsmToken::Identifier: { 1393 SMLoc IdentLoc = Tok.getLoc(); 1394 StringRef Identifier = Tok.getString(); 1395 UpdateLocLex = false; 1396 // Register 1397 unsigned Reg; 1398 if (Tok.isNot(AsmToken::String) && !ParseRegister(Reg, IdentLoc, End)) { 1399 if (SM.onRegister(Reg, ErrMsg)) 1400 return Error(Tok.getLoc(), ErrMsg); 1401 break; 1402 } 1403 // Operator synonymous ("not", "or" etc.) 1404 if ((UpdateLocLex = ParseIntelNamedOperator(Identifier, SM))) 1405 break; 1406 // Symbol reference, when parsing assembly content 1407 InlineAsmIdentifierInfo Info; 1408 const MCExpr *Val; 1409 if (!isParsingInlineAsm()) { 1410 if (getParser().parsePrimaryExpr(Val, End)) { 1411 return Error(Tok.getLoc(), "Unexpected identifier!"); 1412 } else if (SM.onIdentifierExpr(Val, Identifier, Info, false, ErrMsg)) { 1413 return Error(IdentLoc, ErrMsg); 1414 } else 1415 break; 1416 } 1417 // MS InlineAsm operators (TYPE/LENGTH/SIZE) 1418 if (unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) { 1419 if (OpKind == IOK_OFFSET) 1420 return Error(IdentLoc, "Dealing OFFSET operator as part of" 1421 "a compound immediate expression is yet to be supported"); 1422 if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) { 1423 if (SM.onInteger(Val, ErrMsg)) 1424 return Error(IdentLoc, ErrMsg); 1425 } else 1426 return true; 1427 break; 1428 } 1429 // MS Dot Operator expression 1430 if (Identifier.count('.') && PrevTK == AsmToken::RBrac) { 1431 if (ParseIntelDotOperator(SM, End)) 1432 return true; 1433 break; 1434 } 1435 // MS InlineAsm identifier 1436 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info, false, End)) 1437 return true; 1438 else if (SM.onIdentifierExpr(Val, Identifier, Info, true, ErrMsg)) 1439 return Error(IdentLoc, ErrMsg); 1440 break; 1441 } 1442 case AsmToken::Integer: { 1443 // Look for 'b' or 'f' following an Integer as a directional label 1444 SMLoc Loc = getTok().getLoc(); 1445 int64_t IntVal = getTok().getIntVal(); 1446 End = consumeToken(); 1447 UpdateLocLex = false; 1448 if (getLexer().getKind() == AsmToken::Identifier) { 1449 StringRef IDVal = getTok().getString(); 1450 if (IDVal == "f" || IDVal == "b") { 1451 MCSymbol *Sym = 1452 getContext().getDirectionalLocalSymbol(IntVal, IDVal == "b"); 1453 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 1454 const MCExpr *Val = 1455 MCSymbolRefExpr::create(Sym, Variant, getContext()); 1456 if (IDVal == "b" && Sym->isUndefined()) 1457 return Error(Loc, "invalid reference to undefined symbol"); 1458 StringRef Identifier = Sym->getName(); 1459 InlineAsmIdentifierInfo Info; 1460 if (SM.onIdentifierExpr(Val, Identifier, Info, 1461 isParsingInlineAsm(), ErrMsg)) 1462 return Error(Loc, ErrMsg); 1463 End = consumeToken(); 1464 } else { 1465 if (SM.onInteger(IntVal, ErrMsg)) 1466 return Error(Loc, ErrMsg); 1467 } 1468 } else { 1469 if (SM.onInteger(IntVal, ErrMsg)) 1470 return Error(Loc, ErrMsg); 1471 } 1472 break; 1473 } 1474 case AsmToken::Plus: 1475 if (SM.onPlus(ErrMsg)) 1476 return Error(getTok().getLoc(), ErrMsg); 1477 break; 1478 case AsmToken::Minus: 1479 if (SM.onMinus(ErrMsg)) 1480 return Error(getTok().getLoc(), ErrMsg); 1481 break; 1482 case AsmToken::Tilde: SM.onNot(); break; 1483 case AsmToken::Star: SM.onStar(); break; 1484 case AsmToken::Slash: SM.onDivide(); break; 1485 case AsmToken::Percent: SM.onMod(); break; 1486 case AsmToken::Pipe: SM.onOr(); break; 1487 case AsmToken::Caret: SM.onXor(); break; 1488 case AsmToken::Amp: SM.onAnd(); break; 1489 case AsmToken::LessLess: 1490 SM.onLShift(); break; 1491 case AsmToken::GreaterGreater: 1492 SM.onRShift(); break; 1493 case AsmToken::LBrac: 1494 if (SM.onLBrac()) 1495 return Error(Tok.getLoc(), "unexpected bracket encountered"); 1496 break; 1497 case AsmToken::RBrac: 1498 if (SM.onRBrac()) 1499 return Error(Tok.getLoc(), "unexpected bracket encountered"); 1500 break; 1501 case AsmToken::LParen: SM.onLParen(); break; 1502 case AsmToken::RParen: SM.onRParen(); break; 1503 } 1504 if (SM.hadError()) 1505 return Error(Tok.getLoc(), "unknown token in expression"); 1506 1507 if (!Done && UpdateLocLex) 1508 End = consumeToken(); 1509 1510 PrevTK = TK; 1511 } 1512 return false; 1513 } 1514 1515 void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &SM, 1516 SMLoc Start, SMLoc End) { 1517 SMLoc Loc = Start; 1518 unsigned ExprLen = End.getPointer() - Start.getPointer(); 1519 // Skip everything before a symbol displacement (if we have one) 1520 if (SM.getSym()) { 1521 StringRef SymName = SM.getSymName(); 1522 if (unsigned Len = SymName.data() - Start.getPointer()) 1523 InstInfo->AsmRewrites->emplace_back(AOK_Skip, Start, Len); 1524 Loc = SMLoc::getFromPointer(SymName.data() + SymName.size()); 1525 ExprLen = End.getPointer() - (SymName.data() + SymName.size()); 1526 // If we have only a symbol than there's no need for complex rewrite, 1527 // simply skip everything after it 1528 if (!(SM.getBaseReg() || SM.getIndexReg() || SM.getImm())) { 1529 if (ExprLen) 1530 InstInfo->AsmRewrites->emplace_back(AOK_Skip, Loc, ExprLen); 1531 return; 1532 } 1533 } 1534 // Build an Intel Expression rewrite 1535 StringRef BaseRegStr; 1536 StringRef IndexRegStr; 1537 if (SM.getBaseReg()) 1538 BaseRegStr = X86IntelInstPrinter::getRegisterName(SM.getBaseReg()); 1539 if (SM.getIndexReg()) 1540 IndexRegStr = X86IntelInstPrinter::getRegisterName(SM.getIndexReg()); 1541 // Emit it 1542 IntelExpr Expr(BaseRegStr, IndexRegStr, SM.getScale(), SM.getImm(), SM.isMemExpr()); 1543 InstInfo->AsmRewrites->emplace_back(Loc, ExprLen, Expr); 1544 } 1545 1546 // Inline assembly may use variable names with namespace alias qualifiers. 1547 bool X86AsmParser::ParseIntelInlineAsmIdentifier(const MCExpr *&Val, 1548 StringRef &Identifier, 1549 InlineAsmIdentifierInfo &Info, 1550 bool IsUnevaluatedOperand, 1551 SMLoc &End) { 1552 MCAsmParser &Parser = getParser(); 1553 assert(isParsingInlineAsm() && "Expected to be parsing inline assembly."); 1554 Val = nullptr; 1555 1556 StringRef LineBuf(Identifier.data()); 1557 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand); 1558 1559 const AsmToken &Tok = Parser.getTok(); 1560 SMLoc Loc = Tok.getLoc(); 1561 1562 // Advance the token stream until the end of the current token is 1563 // after the end of what the frontend claimed. 1564 const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size(); 1565 do { 1566 End = Tok.getEndLoc(); 1567 getLexer().Lex(); 1568 } while (End.getPointer() < EndPtr); 1569 Identifier = LineBuf; 1570 1571 // The frontend should end parsing on an assembler token boundary, unless it 1572 // failed parsing. 1573 assert((End.getPointer() == EndPtr || 1574 Info.isKind(InlineAsmIdentifierInfo::IK_Invalid)) && 1575 "frontend claimed part of a token?"); 1576 1577 // If the identifier lookup was unsuccessful, assume that we are dealing with 1578 // a label. 1579 if (Info.isKind(InlineAsmIdentifierInfo::IK_Invalid)) { 1580 StringRef InternalName = 1581 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(), 1582 Loc, false); 1583 assert(InternalName.size() && "We should have an internal name here."); 1584 // Push a rewrite for replacing the identifier name with the internal name. 1585 InstInfo->AsmRewrites->emplace_back(AOK_Label, Loc, Identifier.size(), 1586 InternalName); 1587 } else if (Info.isKind(InlineAsmIdentifierInfo::IK_EnumVal)) 1588 return false; 1589 // Create the symbol reference. 1590 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 1591 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 1592 Val = MCSymbolRefExpr::create(Sym, Variant, getParser().getContext()); 1593 return false; 1594 } 1595 1596 //ParseRoundingModeOp - Parse AVX-512 rounding mode operand 1597 std::unique_ptr<X86Operand> 1598 X86AsmParser::ParseRoundingModeOp(SMLoc Start, SMLoc End) { 1599 MCAsmParser &Parser = getParser(); 1600 const AsmToken &Tok = Parser.getTok(); 1601 // Eat "{" and mark the current place. 1602 const SMLoc consumedToken = consumeToken(); 1603 if (Tok.getIdentifier().startswith("r")){ 1604 int rndMode = StringSwitch<int>(Tok.getIdentifier()) 1605 .Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT) 1606 .Case("rd", X86::STATIC_ROUNDING::TO_NEG_INF) 1607 .Case("ru", X86::STATIC_ROUNDING::TO_POS_INF) 1608 .Case("rz", X86::STATIC_ROUNDING::TO_ZERO) 1609 .Default(-1); 1610 if (-1 == rndMode) 1611 return ErrorOperand(Tok.getLoc(), "Invalid rounding mode."); 1612 Parser.Lex(); // Eat "r*" of r*-sae 1613 if (!getLexer().is(AsmToken::Minus)) 1614 return ErrorOperand(Tok.getLoc(), "Expected - at this point"); 1615 Parser.Lex(); // Eat "-" 1616 Parser.Lex(); // Eat the sae 1617 if (!getLexer().is(AsmToken::RCurly)) 1618 return ErrorOperand(Tok.getLoc(), "Expected } at this point"); 1619 Parser.Lex(); // Eat "}" 1620 const MCExpr *RndModeOp = 1621 MCConstantExpr::create(rndMode, Parser.getContext()); 1622 return X86Operand::CreateImm(RndModeOp, Start, End); 1623 } 1624 if(Tok.getIdentifier().equals("sae")){ 1625 Parser.Lex(); // Eat the sae 1626 if (!getLexer().is(AsmToken::RCurly)) 1627 return ErrorOperand(Tok.getLoc(), "Expected } at this point"); 1628 Parser.Lex(); // Eat "}" 1629 return X86Operand::CreateToken("{sae}", consumedToken); 1630 } 1631 return ErrorOperand(Tok.getLoc(), "unknown token in expression"); 1632 } 1633 1634 /// Parse the '.' operator. 1635 bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End) { 1636 const AsmToken &Tok = getTok(); 1637 unsigned Offset; 1638 1639 // Drop the optional '.'. 1640 StringRef DotDispStr = Tok.getString(); 1641 if (DotDispStr.startswith(".")) 1642 DotDispStr = DotDispStr.drop_front(1); 1643 1644 // .Imm gets lexed as a real. 1645 if (Tok.is(AsmToken::Real)) { 1646 APInt DotDisp; 1647 DotDispStr.getAsInteger(10, DotDisp); 1648 Offset = DotDisp.getZExtValue(); 1649 } else if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) { 1650 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.'); 1651 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second, 1652 Offset)) 1653 return Error(Tok.getLoc(), "Unable to lookup field reference!"); 1654 } else 1655 return Error(Tok.getLoc(), "Unexpected token type!"); 1656 1657 // Eat the DotExpression and update End 1658 End = SMLoc::getFromPointer(DotDispStr.data()); 1659 const char *DotExprEndLoc = DotDispStr.data() + DotDispStr.size(); 1660 while (Tok.getLoc().getPointer() < DotExprEndLoc) 1661 Lex(); 1662 SM.addImm(Offset); 1663 return false; 1664 } 1665 1666 /// Parse the 'offset' operator. This operator is used to specify the 1667 /// location rather then the content of a variable. 1668 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() { 1669 MCAsmParser &Parser = getParser(); 1670 const AsmToken &Tok = Parser.getTok(); 1671 SMLoc OffsetOfLoc = Tok.getLoc(); 1672 Parser.Lex(); // Eat offset. 1673 1674 const MCExpr *Val; 1675 InlineAsmIdentifierInfo Info; 1676 SMLoc Start = Tok.getLoc(), End; 1677 StringRef Identifier = Tok.getString(); 1678 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info, 1679 /*Unevaluated=*/false, End)) 1680 return nullptr; 1681 1682 void *Decl = nullptr; 1683 // FIXME: MS evaluates "offset <Constant>" to the underlying integral 1684 if (Info.isKind(InlineAsmIdentifierInfo::IK_EnumVal)) 1685 return ErrorOperand(Start, "offset operator cannot yet handle constants"); 1686 else if (Info.isKind(InlineAsmIdentifierInfo::IK_Var)) 1687 Decl = Info.Var.Decl; 1688 // Don't emit the offset operator. 1689 InstInfo->AsmRewrites->emplace_back(AOK_Skip, OffsetOfLoc, 7); 1690 1691 // The offset operator will have an 'r' constraint, thus we need to create 1692 // register operand to ensure proper matching. Just pick a GPR based on 1693 // the size of a pointer. 1694 bool Parse32 = is32BitMode() || Code16GCC; 1695 unsigned RegNo = is64BitMode() ? X86::RBX : (Parse32 ? X86::EBX : X86::BX); 1696 1697 return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true, 1698 OffsetOfLoc, Identifier, Decl); 1699 } 1700 1701 // Query a candidate string for being an Intel assembly operator 1702 // Report back its kind, or IOK_INVALID if does not evaluated as a known one 1703 unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(StringRef Name) { 1704 return StringSwitch<unsigned>(Name) 1705 .Cases("TYPE","type",IOK_TYPE) 1706 .Cases("SIZE","size",IOK_SIZE) 1707 .Cases("LENGTH","length",IOK_LENGTH) 1708 .Cases("OFFSET","offset",IOK_OFFSET) 1709 .Default(IOK_INVALID); 1710 } 1711 1712 /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator 1713 /// returns the number of elements in an array. It returns the value 1 for 1714 /// non-array variables. The SIZE operator returns the size of a C or C++ 1715 /// variable. A variable's size is the product of its LENGTH and TYPE. The 1716 /// TYPE operator returns the size of a C or C++ type or variable. If the 1717 /// variable is an array, TYPE returns the size of a single element. 1718 unsigned X86AsmParser::ParseIntelInlineAsmOperator(unsigned OpKind) { 1719 MCAsmParser &Parser = getParser(); 1720 const AsmToken &Tok = Parser.getTok(); 1721 Parser.Lex(); // Eat operator. 1722 1723 const MCExpr *Val = nullptr; 1724 InlineAsmIdentifierInfo Info; 1725 SMLoc Start = Tok.getLoc(), End; 1726 StringRef Identifier = Tok.getString(); 1727 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info, 1728 /*Unevaluated=*/true, End)) 1729 return 0; 1730 1731 if (!Info.isKind(InlineAsmIdentifierInfo::IK_Var)) { 1732 Error(Start, "unable to lookup expression"); 1733 return 0; 1734 } 1735 1736 unsigned CVal = 0; 1737 switch(OpKind) { 1738 default: llvm_unreachable("Unexpected operand kind!"); 1739 case IOK_LENGTH: CVal = Info.Var.Length; break; 1740 case IOK_SIZE: CVal = Info.Var.Size; break; 1741 case IOK_TYPE: CVal = Info.Var.Type; break; 1742 } 1743 1744 return CVal; 1745 } 1746 1747 bool X86AsmParser::ParseIntelMemoryOperandSize(unsigned &Size) { 1748 Size = StringSwitch<unsigned>(getTok().getString()) 1749 .Cases("BYTE", "byte", 8) 1750 .Cases("WORD", "word", 16) 1751 .Cases("DWORD", "dword", 32) 1752 .Cases("FLOAT", "float", 32) 1753 .Cases("LONG", "long", 32) 1754 .Cases("FWORD", "fword", 48) 1755 .Cases("DOUBLE", "double", 64) 1756 .Cases("QWORD", "qword", 64) 1757 .Cases("MMWORD","mmword", 64) 1758 .Cases("XWORD", "xword", 80) 1759 .Cases("TBYTE", "tbyte", 80) 1760 .Cases("XMMWORD", "xmmword", 128) 1761 .Cases("YMMWORD", "ymmword", 256) 1762 .Cases("ZMMWORD", "zmmword", 512) 1763 .Cases("OPAQUE", "opaque", -1U) // needs to be non-zero, but doesn't matter 1764 .Default(0); 1765 if (Size) { 1766 const AsmToken &Tok = Lex(); // Eat operand size (e.g., byte, word). 1767 if (!(Tok.getString().equals("PTR") || Tok.getString().equals("ptr"))) 1768 return Error(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!"); 1769 Lex(); // Eat ptr. 1770 } 1771 return false; 1772 } 1773 1774 std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() { 1775 MCAsmParser &Parser = getParser(); 1776 const AsmToken &Tok = Parser.getTok(); 1777 SMLoc Start, End; 1778 1779 // FIXME: Offset operator 1780 // Should be handled as part of immediate expression, as other operators 1781 // Currently, only supported as a stand-alone operand 1782 if (isParsingInlineAsm()) 1783 if (IdentifyIntelInlineAsmOperator(Tok.getString()) == IOK_OFFSET) 1784 return ParseIntelOffsetOfOperator(); 1785 1786 // Parse optional Size directive. 1787 unsigned Size; 1788 if (ParseIntelMemoryOperandSize(Size)) 1789 return nullptr; 1790 bool PtrInOperand = bool(Size); 1791 1792 Start = Tok.getLoc(); 1793 1794 // Rounding mode operand. 1795 if (getSTI().getFeatureBits()[X86::FeatureAVX512] && 1796 getLexer().is(AsmToken::LCurly)) 1797 return ParseRoundingModeOp(Start, End); 1798 1799 // Register operand. 1800 unsigned RegNo = 0; 1801 if (Tok.is(AsmToken::Identifier) && !ParseRegister(RegNo, Start, End)) { 1802 if (RegNo == X86::RIP) 1803 return ErrorOperand(Start, "rip can only be used as a base register"); 1804 // A Register followed by ':' is considered a segment override 1805 if (Tok.isNot(AsmToken::Colon)) 1806 return !PtrInOperand ? X86Operand::CreateReg(RegNo, Start, End) : 1807 ErrorOperand(Start, "expected memory operand after 'ptr', " 1808 "found register operand instead"); 1809 // An alleged segment override. check if we have a valid segment register 1810 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo)) 1811 return ErrorOperand(Start, "invalid segment register"); 1812 // Eat ':' and update Start location 1813 Start = Lex().getLoc(); 1814 } 1815 1816 // Immediates and Memory 1817 IntelExprStateMachine SM; 1818 if (ParseIntelExpression(SM, End)) 1819 return nullptr; 1820 1821 if (isParsingInlineAsm()) 1822 RewriteIntelExpression(SM, Start, Tok.getLoc()); 1823 1824 int64_t Imm = SM.getImm(); 1825 const MCExpr *Disp = SM.getSym(); 1826 const MCExpr *ImmDisp = MCConstantExpr::create(Imm, getContext()); 1827 if (Disp && Imm) 1828 Disp = MCBinaryExpr::createAdd(Disp, ImmDisp, getContext()); 1829 if (!Disp) 1830 Disp = ImmDisp; 1831 1832 // RegNo != 0 specifies a valid segment register, 1833 // and we are parsing a segment override 1834 if (!SM.isMemExpr() && !RegNo) 1835 return X86Operand::CreateImm(Disp, Start, End); 1836 1837 StringRef ErrMsg; 1838 unsigned BaseReg = SM.getBaseReg(); 1839 unsigned IndexReg = SM.getIndexReg(); 1840 unsigned Scale = SM.getScale(); 1841 1842 if ((BaseReg || IndexReg) && 1843 CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, ErrMsg)) 1844 return ErrorOperand(Start, ErrMsg); 1845 if (isParsingInlineAsm()) 1846 return CreateMemForInlineAsm(RegNo, Disp, BaseReg, IndexReg, 1847 Scale, Start, End, Size, SM.getSymName(), 1848 SM.getIdentifierInfo()); 1849 if (!(BaseReg || IndexReg || RegNo)) 1850 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size); 1851 return X86Operand::CreateMem(getPointerWidth(), RegNo, Disp, 1852 BaseReg, IndexReg, Scale, Start, End, Size); 1853 } 1854 1855 std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() { 1856 MCAsmParser &Parser = getParser(); 1857 switch (getLexer().getKind()) { 1858 default: 1859 // Parse a memory operand with no segment register. 1860 return ParseMemOperand(0, Parser.getTok().getLoc()); 1861 case AsmToken::Percent: { 1862 // Read the register. 1863 unsigned RegNo; 1864 SMLoc Start, End; 1865 if (ParseRegister(RegNo, Start, End)) return nullptr; 1866 if (RegNo == X86::EIZ || RegNo == X86::RIZ) { 1867 Error(Start, "%eiz and %riz can only be used as index registers", 1868 SMRange(Start, End)); 1869 return nullptr; 1870 } 1871 if (RegNo == X86::RIP) { 1872 Error(Start, "%rip can only be used as a base register", 1873 SMRange(Start, End)); 1874 return nullptr; 1875 } 1876 1877 // If this is a segment register followed by a ':', then this is the start 1878 // of a memory reference, otherwise this is a normal register reference. 1879 if (getLexer().isNot(AsmToken::Colon)) 1880 return X86Operand::CreateReg(RegNo, Start, End); 1881 1882 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo)) 1883 return ErrorOperand(Start, "invalid segment register"); 1884 1885 getParser().Lex(); // Eat the colon. 1886 return ParseMemOperand(RegNo, Start); 1887 } 1888 case AsmToken::Dollar: { 1889 // $42 -> immediate. 1890 SMLoc Start = Parser.getTok().getLoc(), End; 1891 Parser.Lex(); 1892 const MCExpr *Val; 1893 if (getParser().parseExpression(Val, End)) 1894 return nullptr; 1895 return X86Operand::CreateImm(Val, Start, End); 1896 } 1897 case AsmToken::LCurly:{ 1898 SMLoc Start = Parser.getTok().getLoc(), End; 1899 if (getSTI().getFeatureBits()[X86::FeatureAVX512]) 1900 return ParseRoundingModeOp(Start, End); 1901 return ErrorOperand(Start, "Unexpected '{' in expression"); 1902 } 1903 } 1904 } 1905 1906 // true on failure, false otherwise 1907 // If no {z} mark was found - Parser doesn't advance 1908 bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z, 1909 const SMLoc &StartLoc) { 1910 MCAsmParser &Parser = getParser(); 1911 // Assuming we are just pass the '{' mark, quering the next token 1912 // Searched for {z}, but none was found. Return false, as no parsing error was 1913 // encountered 1914 if (!(getLexer().is(AsmToken::Identifier) && 1915 (getLexer().getTok().getIdentifier() == "z"))) 1916 return false; 1917 Parser.Lex(); // Eat z 1918 // Query and eat the '}' mark 1919 if (!getLexer().is(AsmToken::RCurly)) 1920 return Error(getLexer().getLoc(), "Expected } at this point"); 1921 Parser.Lex(); // Eat '}' 1922 // Assign Z with the {z} mark opernad 1923 Z = X86Operand::CreateToken("{z}", StartLoc); 1924 return false; 1925 } 1926 1927 // true on failure, false otherwise 1928 bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands, 1929 const MCParsedAsmOperand &Op) { 1930 MCAsmParser &Parser = getParser(); 1931 if(getSTI().getFeatureBits()[X86::FeatureAVX512]) { 1932 if (getLexer().is(AsmToken::LCurly)) { 1933 // Eat "{" and mark the current place. 1934 const SMLoc consumedToken = consumeToken(); 1935 // Distinguish {1to<NUM>} from {%k<NUM>}. 1936 if(getLexer().is(AsmToken::Integer)) { 1937 // Parse memory broadcasting ({1to<NUM>}). 1938 if (getLexer().getTok().getIntVal() != 1) 1939 return TokError("Expected 1to<NUM> at this point"); 1940 Parser.Lex(); // Eat "1" of 1to8 1941 if (!getLexer().is(AsmToken::Identifier) || 1942 !getLexer().getTok().getIdentifier().startswith("to")) 1943 return TokError("Expected 1to<NUM> at this point"); 1944 // Recognize only reasonable suffixes. 1945 const char *BroadcastPrimitive = 1946 StringSwitch<const char*>(getLexer().getTok().getIdentifier()) 1947 .Case("to2", "{1to2}") 1948 .Case("to4", "{1to4}") 1949 .Case("to8", "{1to8}") 1950 .Case("to16", "{1to16}") 1951 .Default(nullptr); 1952 if (!BroadcastPrimitive) 1953 return TokError("Invalid memory broadcast primitive."); 1954 Parser.Lex(); // Eat "toN" of 1toN 1955 if (!getLexer().is(AsmToken::RCurly)) 1956 return TokError("Expected } at this point"); 1957 Parser.Lex(); // Eat "}" 1958 Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive, 1959 consumedToken)); 1960 // No AVX512 specific primitives can pass 1961 // after memory broadcasting, so return. 1962 return false; 1963 } else { 1964 // Parse either {k}{z}, {z}{k}, {k} or {z} 1965 // last one have no meaning, but GCC accepts it 1966 // Currently, we're just pass a '{' mark 1967 std::unique_ptr<X86Operand> Z; 1968 if (ParseZ(Z, consumedToken)) 1969 return true; 1970 // Reaching here means that parsing of the allegadly '{z}' mark yielded 1971 // no errors. 1972 // Query for the need of further parsing for a {%k<NUM>} mark 1973 if (!Z || getLexer().is(AsmToken::LCurly)) { 1974 SMLoc StartLoc = Z ? consumeToken() : consumedToken; 1975 // Parse an op-mask register mark ({%k<NUM>}), which is now to be 1976 // expected 1977 unsigned RegNo; 1978 SMLoc RegLoc; 1979 if (!ParseRegister(RegNo, RegLoc, StartLoc) && 1980 X86MCRegisterClasses[X86::VK1RegClassID].contains(RegNo)) { 1981 if (RegNo == X86::K0) 1982 return Error(RegLoc, "Register k0 can't be used as write mask"); 1983 if (!getLexer().is(AsmToken::RCurly)) 1984 return Error(getLexer().getLoc(), "Expected } at this point"); 1985 Operands.push_back(X86Operand::CreateToken("{", StartLoc)); 1986 Operands.push_back( 1987 X86Operand::CreateReg(RegNo, StartLoc, StartLoc)); 1988 Operands.push_back(X86Operand::CreateToken("}", consumeToken())); 1989 } else 1990 return Error(getLexer().getLoc(), 1991 "Expected an op-mask register at this point"); 1992 // {%k<NUM>} mark is found, inquire for {z} 1993 if (getLexer().is(AsmToken::LCurly) && !Z) { 1994 // Have we've found a parsing error, or found no (expected) {z} mark 1995 // - report an error 1996 if (ParseZ(Z, consumeToken()) || !Z) 1997 return Error(getLexer().getLoc(), 1998 "Expected a {z} mark at this point"); 1999 2000 } 2001 // '{z}' on its own is meaningless, hence should be ignored. 2002 // on the contrary - have it been accompanied by a K register, 2003 // allow it. 2004 if (Z) 2005 Operands.push_back(std::move(Z)); 2006 } 2007 } 2008 } 2009 } 2010 return false; 2011 } 2012 2013 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix 2014 /// has already been parsed if present. 2015 std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg, 2016 SMLoc MemStart) { 2017 2018 MCAsmParser &Parser = getParser(); 2019 // We have to disambiguate a parenthesized expression "(4+5)" from the start 2020 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The 2021 // only way to do this without lookahead is to eat the '(' and see what is 2022 // after it. 2023 const MCExpr *Disp = MCConstantExpr::create(0, getParser().getContext()); 2024 if (getLexer().isNot(AsmToken::LParen)) { 2025 SMLoc ExprEnd; 2026 if (getParser().parseExpression(Disp, ExprEnd)) return nullptr; 2027 2028 // After parsing the base expression we could either have a parenthesized 2029 // memory address or not. If not, return now. If so, eat the (. 2030 if (getLexer().isNot(AsmToken::LParen)) { 2031 // Unless we have a segment register, treat this as an immediate. 2032 if (SegReg == 0) 2033 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, ExprEnd); 2034 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1, 2035 MemStart, ExprEnd); 2036 } 2037 2038 // Eat the '('. 2039 Parser.Lex(); 2040 } else { 2041 // Okay, we have a '('. We don't know if this is an expression or not, but 2042 // so we have to eat the ( to see beyond it. 2043 SMLoc LParenLoc = Parser.getTok().getLoc(); 2044 Parser.Lex(); // Eat the '('. 2045 2046 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) { 2047 // Nothing to do here, fall into the code below with the '(' part of the 2048 // memory operand consumed. 2049 } else { 2050 SMLoc ExprEnd; 2051 getLexer().UnLex(AsmToken(AsmToken::LParen, "(")); 2052 2053 // It must be either an parenthesized expression, or an expression that 2054 // begins from a parenthesized expression, parse it now. Example: (1+2) or 2055 // (1+2)+3 2056 if (getParser().parseExpression(Disp, ExprEnd)) 2057 return nullptr; 2058 2059 // After parsing the base expression we could either have a parenthesized 2060 // memory address or not. If not, return now. If so, eat the (. 2061 if (getLexer().isNot(AsmToken::LParen)) { 2062 // Unless we have a segment register, treat this as an immediate. 2063 if (SegReg == 0) 2064 return X86Operand::CreateMem(getPointerWidth(), Disp, LParenLoc, 2065 ExprEnd); 2066 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1, 2067 MemStart, ExprEnd); 2068 } 2069 2070 // Eat the '('. 2071 Parser.Lex(); 2072 } 2073 } 2074 2075 // If we reached here, then we just ate the ( of the memory operand. Process 2076 // the rest of the memory operand. 2077 unsigned BaseReg = 0, IndexReg = 0, Scale = 1; 2078 SMLoc IndexLoc, BaseLoc; 2079 2080 if (getLexer().is(AsmToken::Percent)) { 2081 SMLoc StartLoc, EndLoc; 2082 BaseLoc = Parser.getTok().getLoc(); 2083 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return nullptr; 2084 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) { 2085 Error(StartLoc, "eiz and riz can only be used as index registers", 2086 SMRange(StartLoc, EndLoc)); 2087 return nullptr; 2088 } 2089 } 2090 2091 if (getLexer().is(AsmToken::Comma)) { 2092 Parser.Lex(); // Eat the comma. 2093 IndexLoc = Parser.getTok().getLoc(); 2094 2095 // Following the comma we should have either an index register, or a scale 2096 // value. We don't support the later form, but we want to parse it 2097 // correctly. 2098 // 2099 // Not that even though it would be completely consistent to support syntax 2100 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this. 2101 if (getLexer().is(AsmToken::Percent)) { 2102 SMLoc L; 2103 if (ParseRegister(IndexReg, L, L)) 2104 return nullptr; 2105 if (BaseReg == X86::RIP) { 2106 Error(IndexLoc, "%rip as base register can not have an index register"); 2107 return nullptr; 2108 } 2109 if (IndexReg == X86::RIP) { 2110 Error(IndexLoc, "%rip is not allowed as an index register"); 2111 return nullptr; 2112 } 2113 2114 if (getLexer().isNot(AsmToken::RParen)) { 2115 // Parse the scale amount: 2116 // ::= ',' [scale-expression] 2117 if (getLexer().isNot(AsmToken::Comma)) { 2118 Error(Parser.getTok().getLoc(), 2119 "expected comma in scale expression"); 2120 return nullptr; 2121 } 2122 Parser.Lex(); // Eat the comma. 2123 2124 if (getLexer().isNot(AsmToken::RParen)) { 2125 SMLoc Loc = Parser.getTok().getLoc(); 2126 2127 int64_t ScaleVal; 2128 if (getParser().parseAbsoluteExpression(ScaleVal)){ 2129 Error(Loc, "expected scale expression"); 2130 return nullptr; 2131 } 2132 2133 // Validate the scale amount. 2134 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) && 2135 ScaleVal != 1) { 2136 Error(Loc, "scale factor in 16-bit address must be 1"); 2137 return nullptr; 2138 } 2139 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && 2140 ScaleVal != 8) { 2141 Error(Loc, "scale factor in address must be 1, 2, 4 or 8"); 2142 return nullptr; 2143 } 2144 Scale = (unsigned)ScaleVal; 2145 } 2146 } 2147 } else if (getLexer().isNot(AsmToken::RParen)) { 2148 // A scale amount without an index is ignored. 2149 // index. 2150 SMLoc Loc = Parser.getTok().getLoc(); 2151 2152 int64_t Value; 2153 if (getParser().parseAbsoluteExpression(Value)) 2154 return nullptr; 2155 2156 if (Value != 1) 2157 Warning(Loc, "scale factor without index register is ignored"); 2158 Scale = 1; 2159 } 2160 } 2161 2162 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too. 2163 if (getLexer().isNot(AsmToken::RParen)) { 2164 Error(Parser.getTok().getLoc(), "unexpected token in memory operand"); 2165 return nullptr; 2166 } 2167 SMLoc MemEnd = Parser.getTok().getEndLoc(); 2168 Parser.Lex(); // Eat the ')'. 2169 2170 // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed, 2171 // and then only in non-64-bit modes. Except for DX, which is a special case 2172 // because an unofficial form of in/out instructions uses it. 2173 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) && 2174 (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP && 2175 BaseReg != X86::SI && BaseReg != X86::DI)) && 2176 BaseReg != X86::DX) { 2177 Error(BaseLoc, "invalid 16-bit base register"); 2178 return nullptr; 2179 } 2180 if (BaseReg == 0 && 2181 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) { 2182 Error(IndexLoc, "16-bit memory operand may not include only index register"); 2183 return nullptr; 2184 } 2185 2186 StringRef ErrMsg; 2187 if (CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, ErrMsg)) { 2188 Error(BaseLoc, ErrMsg); 2189 return nullptr; 2190 } 2191 2192 if (SegReg || BaseReg || IndexReg) 2193 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg, 2194 IndexReg, Scale, MemStart, MemEnd); 2195 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, MemEnd); 2196 } 2197 2198 bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 2199 SMLoc NameLoc, OperandVector &Operands) { 2200 MCAsmParser &Parser = getParser(); 2201 InstInfo = &Info; 2202 StringRef PatchedName = Name; 2203 2204 if ((Name.equals("jmp") || Name.equals("jc") || Name.equals("jz")) && 2205 isParsingIntelSyntax() && isParsingInlineAsm()) { 2206 StringRef NextTok = Parser.getTok().getString(); 2207 if (NextTok == "short") { 2208 SMLoc NameEndLoc = 2209 NameLoc.getFromPointer(NameLoc.getPointer() + Name.size()); 2210 // Eat the short keyword 2211 Parser.Lex(); 2212 // MS ignores the short keyword, it determines the jmp type based 2213 // on the distance of the label 2214 InstInfo->AsmRewrites->emplace_back(AOK_Skip, NameEndLoc, 2215 NextTok.size() + 1); 2216 } 2217 } 2218 2219 // FIXME: Hack to recognize setneb as setne. 2220 if (PatchedName.startswith("set") && PatchedName.endswith("b") && 2221 PatchedName != "setb" && PatchedName != "setnb") 2222 PatchedName = PatchedName.substr(0, Name.size()-1); 2223 2224 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}. 2225 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) && 2226 (PatchedName.endswith("ss") || PatchedName.endswith("sd") || 2227 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) { 2228 bool IsVCMP = PatchedName[0] == 'v'; 2229 unsigned CCIdx = IsVCMP ? 4 : 3; 2230 unsigned ComparisonCode = StringSwitch<unsigned>( 2231 PatchedName.slice(CCIdx, PatchedName.size() - 2)) 2232 .Case("eq", 0x00) 2233 .Case("eq_oq", 0x00) 2234 .Case("lt", 0x01) 2235 .Case("lt_os", 0x01) 2236 .Case("le", 0x02) 2237 .Case("le_os", 0x02) 2238 .Case("unord", 0x03) 2239 .Case("unord_q", 0x03) 2240 .Case("neq", 0x04) 2241 .Case("neq_uq", 0x04) 2242 .Case("nlt", 0x05) 2243 .Case("nlt_us", 0x05) 2244 .Case("nle", 0x06) 2245 .Case("nle_us", 0x06) 2246 .Case("ord", 0x07) 2247 .Case("ord_q", 0x07) 2248 /* AVX only from here */ 2249 .Case("eq_uq", 0x08) 2250 .Case("nge", 0x09) 2251 .Case("nge_us", 0x09) 2252 .Case("ngt", 0x0A) 2253 .Case("ngt_us", 0x0A) 2254 .Case("false", 0x0B) 2255 .Case("false_oq", 0x0B) 2256 .Case("neq_oq", 0x0C) 2257 .Case("ge", 0x0D) 2258 .Case("ge_os", 0x0D) 2259 .Case("gt", 0x0E) 2260 .Case("gt_os", 0x0E) 2261 .Case("true", 0x0F) 2262 .Case("true_uq", 0x0F) 2263 .Case("eq_os", 0x10) 2264 .Case("lt_oq", 0x11) 2265 .Case("le_oq", 0x12) 2266 .Case("unord_s", 0x13) 2267 .Case("neq_us", 0x14) 2268 .Case("nlt_uq", 0x15) 2269 .Case("nle_uq", 0x16) 2270 .Case("ord_s", 0x17) 2271 .Case("eq_us", 0x18) 2272 .Case("nge_uq", 0x19) 2273 .Case("ngt_uq", 0x1A) 2274 .Case("false_os", 0x1B) 2275 .Case("neq_os", 0x1C) 2276 .Case("ge_oq", 0x1D) 2277 .Case("gt_oq", 0x1E) 2278 .Case("true_us", 0x1F) 2279 .Default(~0U); 2280 if (ComparisonCode != ~0U && (IsVCMP || ComparisonCode < 8)) { 2281 2282 Operands.push_back(X86Operand::CreateToken(PatchedName.slice(0, CCIdx), 2283 NameLoc)); 2284 2285 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode, 2286 getParser().getContext()); 2287 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc)); 2288 2289 PatchedName = PatchedName.substr(PatchedName.size() - 2); 2290 } 2291 } 2292 2293 // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}. 2294 if (PatchedName.startswith("vpcmp") && 2295 (PatchedName.endswith("b") || PatchedName.endswith("w") || 2296 PatchedName.endswith("d") || PatchedName.endswith("q"))) { 2297 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1; 2298 unsigned ComparisonCode = StringSwitch<unsigned>( 2299 PatchedName.slice(5, PatchedName.size() - CCIdx)) 2300 .Case("eq", 0x0) // Only allowed on unsigned. Checked below. 2301 .Case("lt", 0x1) 2302 .Case("le", 0x2) 2303 //.Case("false", 0x3) // Not a documented alias. 2304 .Case("neq", 0x4) 2305 .Case("nlt", 0x5) 2306 .Case("nle", 0x6) 2307 //.Case("true", 0x7) // Not a documented alias. 2308 .Default(~0U); 2309 if (ComparisonCode != ~0U && (ComparisonCode != 0 || CCIdx == 2)) { 2310 Operands.push_back(X86Operand::CreateToken("vpcmp", NameLoc)); 2311 2312 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode, 2313 getParser().getContext()); 2314 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc)); 2315 2316 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx); 2317 } 2318 } 2319 2320 // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}. 2321 if (PatchedName.startswith("vpcom") && 2322 (PatchedName.endswith("b") || PatchedName.endswith("w") || 2323 PatchedName.endswith("d") || PatchedName.endswith("q"))) { 2324 unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1; 2325 unsigned ComparisonCode = StringSwitch<unsigned>( 2326 PatchedName.slice(5, PatchedName.size() - CCIdx)) 2327 .Case("lt", 0x0) 2328 .Case("le", 0x1) 2329 .Case("gt", 0x2) 2330 .Case("ge", 0x3) 2331 .Case("eq", 0x4) 2332 .Case("neq", 0x5) 2333 .Case("false", 0x6) 2334 .Case("true", 0x7) 2335 .Default(~0U); 2336 if (ComparisonCode != ~0U) { 2337 Operands.push_back(X86Operand::CreateToken("vpcom", NameLoc)); 2338 2339 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode, 2340 getParser().getContext()); 2341 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc)); 2342 2343 PatchedName = PatchedName.substr(PatchedName.size() - CCIdx); 2344 } 2345 } 2346 2347 2348 // Determine whether this is an instruction prefix. 2349 // FIXME: 2350 // Enhance prefixes integrity robustness. for example, following forms 2351 // are currently tolerated: 2352 // repz repnz <insn> ; GAS errors for the use of two similar prefixes 2353 // lock addq %rax, %rbx ; Destination operand must be of memory type 2354 // xacquire <insn> ; xacquire must be accompanied by 'lock' 2355 bool isPrefix = StringSwitch<bool>(Name) 2356 .Cases("rex64", "data32", "data16", true) 2357 .Cases("xacquire", "xrelease", true) 2358 .Cases("acquire", "release", isParsingIntelSyntax()) 2359 .Default(false); 2360 2361 auto isLockRepeatPrefix = [](StringRef N) { 2362 return StringSwitch<bool>(N) 2363 .Cases("lock", "rep", "repe", "repz", "repne", "repnz", true) 2364 .Default(false); 2365 }; 2366 2367 bool CurlyAsEndOfStatement = false; 2368 2369 unsigned Flags = X86::IP_NO_PREFIX; 2370 while (isLockRepeatPrefix(Name.lower())) { 2371 unsigned Prefix = 2372 StringSwitch<unsigned>(Name) 2373 .Cases("lock", "lock", X86::IP_HAS_LOCK) 2374 .Cases("rep", "repe", "repz", X86::IP_HAS_REPEAT) 2375 .Cases("repne", "repnz", X86::IP_HAS_REPEAT_NE) 2376 .Default(X86::IP_NO_PREFIX); // Invalid prefix (impossible) 2377 Flags |= Prefix; 2378 Name = Parser.getTok().getString(); 2379 Parser.Lex(); // eat the prefix 2380 // Hack: we could have something like 2381 // "lock; cmpxchg16b $1" or "lock\0A\09incl" or "lock/incl" 2382 while (Name.startswith(";") || Name.startswith("\n") || 2383 Name.startswith("\t") || Name.startswith("/")) { 2384 Name = Parser.getTok().getString(); 2385 Parser.Lex(); // go to next prefix or instr 2386 } 2387 } 2388 2389 if (Flags) 2390 PatchedName = Name; 2391 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc)); 2392 2393 // This does the actual operand parsing. Don't parse any more if we have a 2394 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we 2395 // just want to parse the "lock" as the first instruction and the "incl" as 2396 // the next one. 2397 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) { 2398 // Parse '*' modifier. 2399 if (getLexer().is(AsmToken::Star)) 2400 Operands.push_back(X86Operand::CreateToken("*", consumeToken())); 2401 2402 // Read the operands. 2403 while(1) { 2404 if (std::unique_ptr<X86Operand> Op = ParseOperand()) { 2405 Operands.push_back(std::move(Op)); 2406 if (HandleAVX512Operand(Operands, *Operands.back())) 2407 return true; 2408 } else { 2409 return true; 2410 } 2411 // check for comma and eat it 2412 if (getLexer().is(AsmToken::Comma)) 2413 Parser.Lex(); 2414 else 2415 break; 2416 } 2417 2418 // In MS inline asm curly braces mark the beginning/end of a block, 2419 // therefore they should be interepreted as end of statement 2420 CurlyAsEndOfStatement = 2421 isParsingIntelSyntax() && isParsingInlineAsm() && 2422 (getLexer().is(AsmToken::LCurly) || getLexer().is(AsmToken::RCurly)); 2423 if (getLexer().isNot(AsmToken::EndOfStatement) && !CurlyAsEndOfStatement) 2424 return TokError("unexpected token in argument list"); 2425 } 2426 2427 // Consume the EndOfStatement or the prefix separator Slash 2428 if (getLexer().is(AsmToken::EndOfStatement) || 2429 (isPrefix && getLexer().is(AsmToken::Slash))) 2430 Parser.Lex(); 2431 else if (CurlyAsEndOfStatement) 2432 // Add an actual EndOfStatement before the curly brace 2433 Info.AsmRewrites->emplace_back(AOK_EndOfStatement, 2434 getLexer().getTok().getLoc(), 0); 2435 2436 // This is for gas compatibility and cannot be done in td. 2437 // Adding "p" for some floating point with no argument. 2438 // For example: fsub --> fsubp 2439 bool IsFp = 2440 Name == "fsub" || Name == "fdiv" || Name == "fsubr" || Name == "fdivr"; 2441 if (IsFp && Operands.size() == 1) { 2442 const char *Repl = StringSwitch<const char *>(Name) 2443 .Case("fsub", "fsubp") 2444 .Case("fdiv", "fdivp") 2445 .Case("fsubr", "fsubrp") 2446 .Case("fdivr", "fdivrp"); 2447 static_cast<X86Operand &>(*Operands[0]).setTokenValue(Repl); 2448 } 2449 2450 // Moving a 32 or 16 bit value into a segment register has the same 2451 // behavior. Modify such instructions to always take shorter form. 2452 if ((Name == "mov" || Name == "movw" || Name == "movl") && 2453 (Operands.size() == 3)) { 2454 X86Operand &Op1 = (X86Operand &)*Operands[1]; 2455 X86Operand &Op2 = (X86Operand &)*Operands[2]; 2456 SMLoc Loc = Op1.getEndLoc(); 2457 if (Op1.isReg() && Op2.isReg() && 2458 X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains( 2459 Op2.getReg()) && 2460 (X86MCRegisterClasses[X86::GR16RegClassID].contains(Op1.getReg()) || 2461 X86MCRegisterClasses[X86::GR32RegClassID].contains(Op1.getReg()))) { 2462 // Change instruction name to match new instruction. 2463 if (Name != "mov" && Name[3] == (is16BitMode() ? 'l' : 'w')) { 2464 Name = is16BitMode() ? "movw" : "movl"; 2465 Operands[0] = X86Operand::CreateToken(Name, NameLoc); 2466 } 2467 // Select the correct equivalent 16-/32-bit source register. 2468 unsigned Reg = 2469 getX86SubSuperRegisterOrZero(Op1.getReg(), is16BitMode() ? 16 : 32); 2470 Operands[1] = X86Operand::CreateReg(Reg, Loc, Loc); 2471 } 2472 } 2473 2474 // This is a terrible hack to handle "out[s]?[bwl]? %al, (%dx)" -> 2475 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely 2476 // documented form in various unofficial manuals, so a lot of code uses it. 2477 if ((Name == "outb" || Name == "outsb" || Name == "outw" || Name == "outsw" || 2478 Name == "outl" || Name == "outsl" || Name == "out" || Name == "outs") && 2479 Operands.size() == 3) { 2480 X86Operand &Op = (X86Operand &)*Operands.back(); 2481 if (Op.isMem() && Op.Mem.SegReg == 0 && 2482 isa<MCConstantExpr>(Op.Mem.Disp) && 2483 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 && 2484 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) { 2485 SMLoc Loc = Op.getEndLoc(); 2486 Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc); 2487 } 2488 } 2489 // Same hack for "in[s]?[bwl]? (%dx), %al" -> "inb %dx, %al". 2490 if ((Name == "inb" || Name == "insb" || Name == "inw" || Name == "insw" || 2491 Name == "inl" || Name == "insl" || Name == "in" || Name == "ins") && 2492 Operands.size() == 3) { 2493 X86Operand &Op = (X86Operand &)*Operands[1]; 2494 if (Op.isMem() && Op.Mem.SegReg == 0 && 2495 isa<MCConstantExpr>(Op.Mem.Disp) && 2496 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 && 2497 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) { 2498 SMLoc Loc = Op.getEndLoc(); 2499 Operands[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc); 2500 } 2501 } 2502 2503 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 2> TmpOperands; 2504 bool HadVerifyError = false; 2505 2506 // Append default arguments to "ins[bwld]" 2507 if (Name.startswith("ins") && 2508 (Operands.size() == 1 || Operands.size() == 3) && 2509 (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd" || 2510 Name == "ins")) { 2511 2512 AddDefaultSrcDestOperands(TmpOperands, 2513 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc), 2514 DefaultMemDIOperand(NameLoc)); 2515 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands); 2516 } 2517 2518 // Append default arguments to "outs[bwld]" 2519 if (Name.startswith("outs") && 2520 (Operands.size() == 1 || Operands.size() == 3) && 2521 (Name == "outsb" || Name == "outsw" || Name == "outsl" || 2522 Name == "outsd" || Name == "outs")) { 2523 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc), 2524 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc)); 2525 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands); 2526 } 2527 2528 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate 2529 // values of $SIREG according to the mode. It would be nice if this 2530 // could be achieved with InstAlias in the tables. 2531 if (Name.startswith("lods") && 2532 (Operands.size() == 1 || Operands.size() == 2) && 2533 (Name == "lods" || Name == "lodsb" || Name == "lodsw" || 2534 Name == "lodsl" || Name == "lodsd" || Name == "lodsq")) { 2535 TmpOperands.push_back(DefaultMemSIOperand(NameLoc)); 2536 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands); 2537 } 2538 2539 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate 2540 // values of $DIREG according to the mode. It would be nice if this 2541 // could be achieved with InstAlias in the tables. 2542 if (Name.startswith("stos") && 2543 (Operands.size() == 1 || Operands.size() == 2) && 2544 (Name == "stos" || Name == "stosb" || Name == "stosw" || 2545 Name == "stosl" || Name == "stosd" || Name == "stosq")) { 2546 TmpOperands.push_back(DefaultMemDIOperand(NameLoc)); 2547 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands); 2548 } 2549 2550 // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate 2551 // values of $DIREG according to the mode. It would be nice if this 2552 // could be achieved with InstAlias in the tables. 2553 if (Name.startswith("scas") && 2554 (Operands.size() == 1 || Operands.size() == 2) && 2555 (Name == "scas" || Name == "scasb" || Name == "scasw" || 2556 Name == "scasl" || Name == "scasd" || Name == "scasq")) { 2557 TmpOperands.push_back(DefaultMemDIOperand(NameLoc)); 2558 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands); 2559 } 2560 2561 // Add default SI and DI operands to "cmps[bwlq]". 2562 if (Name.startswith("cmps") && 2563 (Operands.size() == 1 || Operands.size() == 3) && 2564 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" || 2565 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) { 2566 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc), 2567 DefaultMemSIOperand(NameLoc)); 2568 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands); 2569 } 2570 2571 // Add default SI and DI operands to "movs[bwlq]". 2572 if (((Name.startswith("movs") && 2573 (Name == "movs" || Name == "movsb" || Name == "movsw" || 2574 Name == "movsl" || Name == "movsd" || Name == "movsq")) || 2575 (Name.startswith("smov") && 2576 (Name == "smov" || Name == "smovb" || Name == "smovw" || 2577 Name == "smovl" || Name == "smovd" || Name == "smovq"))) && 2578 (Operands.size() == 1 || Operands.size() == 3)) { 2579 if (Name == "movsd" && Operands.size() == 1 && !isParsingIntelSyntax()) 2580 Operands.back() = X86Operand::CreateToken("movsl", NameLoc); 2581 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc), 2582 DefaultMemDIOperand(NameLoc)); 2583 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands); 2584 } 2585 2586 // Check if we encountered an error for one the string insturctions 2587 if (HadVerifyError) { 2588 return HadVerifyError; 2589 } 2590 2591 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to 2592 // "shift <op>". 2593 if ((Name.startswith("shr") || Name.startswith("sar") || 2594 Name.startswith("shl") || Name.startswith("sal") || 2595 Name.startswith("rcl") || Name.startswith("rcr") || 2596 Name.startswith("rol") || Name.startswith("ror")) && 2597 Operands.size() == 3) { 2598 if (isParsingIntelSyntax()) { 2599 // Intel syntax 2600 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[2]); 2601 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) && 2602 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1) 2603 Operands.pop_back(); 2604 } else { 2605 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]); 2606 if (Op1.isImm() && isa<MCConstantExpr>(Op1.getImm()) && 2607 cast<MCConstantExpr>(Op1.getImm())->getValue() == 1) 2608 Operands.erase(Operands.begin() + 1); 2609 } 2610 } 2611 2612 // Transforms "int $3" into "int3" as a size optimization. We can't write an 2613 // instalias with an immediate operand yet. 2614 if (Name == "int" && Operands.size() == 2) { 2615 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]); 2616 if (Op1.isImm()) 2617 if (auto *CE = dyn_cast<MCConstantExpr>(Op1.getImm())) 2618 if (CE->getValue() == 3) { 2619 Operands.erase(Operands.begin() + 1); 2620 static_cast<X86Operand &>(*Operands[0]).setTokenValue("int3"); 2621 } 2622 } 2623 2624 // Transforms "xlat mem8" into "xlatb" 2625 if ((Name == "xlat" || Name == "xlatb") && Operands.size() == 2) { 2626 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]); 2627 if (Op1.isMem8()) { 2628 Warning(Op1.getStartLoc(), "memory operand is only for determining the " 2629 "size, (R|E)BX will be used for the location"); 2630 Operands.pop_back(); 2631 static_cast<X86Operand &>(*Operands[0]).setTokenValue("xlatb"); 2632 } 2633 } 2634 2635 if (Flags) 2636 Operands.push_back(X86Operand::CreatePrefix(Flags, NameLoc, NameLoc)); 2637 return false; 2638 } 2639 2640 bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) { 2641 return false; 2642 } 2643 2644 bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) { 2645 const MCRegisterInfo *MRI = getContext().getRegisterInfo(); 2646 2647 switch (Inst.getOpcode()) { 2648 case X86::VGATHERDPDYrm: 2649 case X86::VGATHERDPDrm: 2650 case X86::VGATHERDPSYrm: 2651 case X86::VGATHERDPSrm: 2652 case X86::VGATHERQPDYrm: 2653 case X86::VGATHERQPDrm: 2654 case X86::VGATHERQPSYrm: 2655 case X86::VGATHERQPSrm: 2656 case X86::VPGATHERDDYrm: 2657 case X86::VPGATHERDDrm: 2658 case X86::VPGATHERDQYrm: 2659 case X86::VPGATHERDQrm: 2660 case X86::VPGATHERQDYrm: 2661 case X86::VPGATHERQDrm: 2662 case X86::VPGATHERQQYrm: 2663 case X86::VPGATHERQQrm: { 2664 unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg()); 2665 unsigned Mask = MRI->getEncodingValue(Inst.getOperand(1).getReg()); 2666 unsigned Index = 2667 MRI->getEncodingValue(Inst.getOperand(3 + X86::AddrIndexReg).getReg()); 2668 if (Dest == Mask || Dest == Index || Mask == Index) 2669 return Warning(Ops[0]->getStartLoc(), "mask, index, and destination " 2670 "registers should be distinct"); 2671 break; 2672 } 2673 case X86::VGATHERDPDZ128rm: 2674 case X86::VGATHERDPDZ256rm: 2675 case X86::VGATHERDPDZrm: 2676 case X86::VGATHERDPSZ128rm: 2677 case X86::VGATHERDPSZ256rm: 2678 case X86::VGATHERDPSZrm: 2679 case X86::VGATHERQPDZ128rm: 2680 case X86::VGATHERQPDZ256rm: 2681 case X86::VGATHERQPDZrm: 2682 case X86::VGATHERQPSZ128rm: 2683 case X86::VGATHERQPSZ256rm: 2684 case X86::VGATHERQPSZrm: 2685 case X86::VPGATHERDDZ128rm: 2686 case X86::VPGATHERDDZ256rm: 2687 case X86::VPGATHERDDZrm: 2688 case X86::VPGATHERDQZ128rm: 2689 case X86::VPGATHERDQZ256rm: 2690 case X86::VPGATHERDQZrm: 2691 case X86::VPGATHERQDZ128rm: 2692 case X86::VPGATHERQDZ256rm: 2693 case X86::VPGATHERQDZrm: 2694 case X86::VPGATHERQQZ128rm: 2695 case X86::VPGATHERQQZ256rm: 2696 case X86::VPGATHERQQZrm: { 2697 unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg()); 2698 unsigned Index = 2699 MRI->getEncodingValue(Inst.getOperand(4 + X86::AddrIndexReg).getReg()); 2700 if (Dest == Index) 2701 return Warning(Ops[0]->getStartLoc(), "index and destination registers " 2702 "should be distinct"); 2703 break; 2704 } 2705 } 2706 2707 return false; 2708 } 2709 2710 static const char *getSubtargetFeatureName(uint64_t Val); 2711 2712 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands, 2713 MCStreamer &Out) { 2714 Instrumentation->InstrumentAndEmitInstruction( 2715 Inst, Operands, getContext(), MII, Out, 2716 getParser().shouldPrintSchedInfo()); 2717 } 2718 2719 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 2720 OperandVector &Operands, 2721 MCStreamer &Out, uint64_t &ErrorInfo, 2722 bool MatchingInlineAsm) { 2723 if (isParsingIntelSyntax()) 2724 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo, 2725 MatchingInlineAsm); 2726 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo, 2727 MatchingInlineAsm); 2728 } 2729 2730 void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, 2731 OperandVector &Operands, MCStreamer &Out, 2732 bool MatchingInlineAsm) { 2733 // FIXME: This should be replaced with a real .td file alias mechanism. 2734 // Also, MatchInstructionImpl should actually *do* the EmitInstruction 2735 // call. 2736 const char *Repl = StringSwitch<const char *>(Op.getToken()) 2737 .Case("finit", "fninit") 2738 .Case("fsave", "fnsave") 2739 .Case("fstcw", "fnstcw") 2740 .Case("fstcww", "fnstcw") 2741 .Case("fstenv", "fnstenv") 2742 .Case("fstsw", "fnstsw") 2743 .Case("fstsww", "fnstsw") 2744 .Case("fclex", "fnclex") 2745 .Default(nullptr); 2746 if (Repl) { 2747 MCInst Inst; 2748 Inst.setOpcode(X86::WAIT); 2749 Inst.setLoc(IDLoc); 2750 if (!MatchingInlineAsm) 2751 EmitInstruction(Inst, Operands, Out); 2752 Operands[0] = X86Operand::CreateToken(Repl, IDLoc); 2753 } 2754 } 2755 2756 bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc, uint64_t ErrorInfo, 2757 bool MatchingInlineAsm) { 2758 assert(ErrorInfo && "Unknown missing feature!"); 2759 SmallString<126> Msg; 2760 raw_svector_ostream OS(Msg); 2761 OS << "instruction requires:"; 2762 uint64_t Mask = 1; 2763 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) { 2764 if (ErrorInfo & Mask) 2765 OS << ' ' << getSubtargetFeatureName(ErrorInfo & Mask); 2766 Mask <<= 1; 2767 } 2768 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm); 2769 } 2770 2771 static unsigned getPrefixes(OperandVector &Operands) { 2772 unsigned Result = 0; 2773 X86Operand &Prefix = static_cast<X86Operand &>(*Operands.back()); 2774 if (Prefix.isPrefix()) { 2775 Result = Prefix.getPrefix(); 2776 Operands.pop_back(); 2777 } 2778 return Result; 2779 } 2780 2781 bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode, 2782 OperandVector &Operands, 2783 MCStreamer &Out, 2784 uint64_t &ErrorInfo, 2785 bool MatchingInlineAsm) { 2786 assert(!Operands.empty() && "Unexpect empty operand list!"); 2787 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]); 2788 assert(Op.isToken() && "Leading operand should always be a mnemonic!"); 2789 SMRange EmptyRange = None; 2790 2791 // First, handle aliases that expand to multiple instructions. 2792 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm); 2793 2794 bool WasOriginallyInvalidOperand = false; 2795 unsigned Prefixes = getPrefixes(Operands); 2796 2797 MCInst Inst; 2798 2799 if (Prefixes) 2800 Inst.setFlags(Prefixes); 2801 2802 // First, try a direct match. 2803 switch (MatchInstruction(Operands, Inst, ErrorInfo, MatchingInlineAsm, 2804 isParsingIntelSyntax())) { 2805 default: llvm_unreachable("Unexpected match result!"); 2806 case Match_Success: 2807 if (!MatchingInlineAsm && validateInstruction(Inst, Operands)) 2808 return true; 2809 // Some instructions need post-processing to, for example, tweak which 2810 // encoding is selected. Loop on it while changes happen so the 2811 // individual transformations can chain off each other. 2812 if (!MatchingInlineAsm) 2813 while (processInstruction(Inst, Operands)) 2814 ; 2815 2816 Inst.setLoc(IDLoc); 2817 if (!MatchingInlineAsm) 2818 EmitInstruction(Inst, Operands, Out); 2819 Opcode = Inst.getOpcode(); 2820 return false; 2821 case Match_MissingFeature: 2822 return ErrorMissingFeature(IDLoc, ErrorInfo, MatchingInlineAsm); 2823 case Match_InvalidOperand: 2824 WasOriginallyInvalidOperand = true; 2825 break; 2826 case Match_MnemonicFail: 2827 break; 2828 } 2829 2830 // FIXME: Ideally, we would only attempt suffix matches for things which are 2831 // valid prefixes, and we could just infer the right unambiguous 2832 // type. However, that requires substantially more matcher support than the 2833 // following hack. 2834 2835 // Change the operand to point to a temporary token. 2836 StringRef Base = Op.getToken(); 2837 SmallString<16> Tmp; 2838 Tmp += Base; 2839 Tmp += ' '; 2840 Op.setTokenValue(Tmp); 2841 2842 // If this instruction starts with an 'f', then it is a floating point stack 2843 // instruction. These come in up to three forms for 32-bit, 64-bit, and 2844 // 80-bit floating point, which use the suffixes s,l,t respectively. 2845 // 2846 // Otherwise, we assume that this may be an integer instruction, which comes 2847 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively. 2848 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0"; 2849 2850 // Check for the various suffix matches. 2851 uint64_t ErrorInfoIgnore; 2852 uint64_t ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings. 2853 unsigned Match[4]; 2854 2855 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) { 2856 Tmp.back() = Suffixes[I]; 2857 Match[I] = MatchInstruction(Operands, Inst, ErrorInfoIgnore, 2858 MatchingInlineAsm, isParsingIntelSyntax()); 2859 // If this returned as a missing feature failure, remember that. 2860 if (Match[I] == Match_MissingFeature) 2861 ErrorInfoMissingFeature = ErrorInfoIgnore; 2862 } 2863 2864 // Restore the old token. 2865 Op.setTokenValue(Base); 2866 2867 // If exactly one matched, then we treat that as a successful match (and the 2868 // instruction will already have been filled in correctly, since the failing 2869 // matches won't have modified it). 2870 unsigned NumSuccessfulMatches = 2871 std::count(std::begin(Match), std::end(Match), Match_Success); 2872 if (NumSuccessfulMatches == 1) { 2873 Inst.setLoc(IDLoc); 2874 if (!MatchingInlineAsm) 2875 EmitInstruction(Inst, Operands, Out); 2876 Opcode = Inst.getOpcode(); 2877 return false; 2878 } 2879 2880 // Otherwise, the match failed, try to produce a decent error message. 2881 2882 // If we had multiple suffix matches, then identify this as an ambiguous 2883 // match. 2884 if (NumSuccessfulMatches > 1) { 2885 char MatchChars[4]; 2886 unsigned NumMatches = 0; 2887 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) 2888 if (Match[I] == Match_Success) 2889 MatchChars[NumMatches++] = Suffixes[I]; 2890 2891 SmallString<126> Msg; 2892 raw_svector_ostream OS(Msg); 2893 OS << "ambiguous instructions require an explicit suffix (could be "; 2894 for (unsigned i = 0; i != NumMatches; ++i) { 2895 if (i != 0) 2896 OS << ", "; 2897 if (i + 1 == NumMatches) 2898 OS << "or "; 2899 OS << "'" << Base << MatchChars[i] << "'"; 2900 } 2901 OS << ")"; 2902 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm); 2903 return true; 2904 } 2905 2906 // Okay, we know that none of the variants matched successfully. 2907 2908 // If all of the instructions reported an invalid mnemonic, then the original 2909 // mnemonic was invalid. 2910 if (std::count(std::begin(Match), std::end(Match), Match_MnemonicFail) == 4) { 2911 if (!WasOriginallyInvalidOperand) { 2912 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'", 2913 Op.getLocRange(), MatchingInlineAsm); 2914 } 2915 2916 // Recover location info for the operand if we know which was the problem. 2917 if (ErrorInfo != ~0ULL) { 2918 if (ErrorInfo >= Operands.size()) 2919 return Error(IDLoc, "too few operands for instruction", EmptyRange, 2920 MatchingInlineAsm); 2921 2922 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo]; 2923 if (Operand.getStartLoc().isValid()) { 2924 SMRange OperandRange = Operand.getLocRange(); 2925 return Error(Operand.getStartLoc(), "invalid operand for instruction", 2926 OperandRange, MatchingInlineAsm); 2927 } 2928 } 2929 2930 return Error(IDLoc, "invalid operand for instruction", EmptyRange, 2931 MatchingInlineAsm); 2932 } 2933 2934 // If one instruction matched with a missing feature, report this as a 2935 // missing feature. 2936 if (std::count(std::begin(Match), std::end(Match), 2937 Match_MissingFeature) == 1) { 2938 ErrorInfo = ErrorInfoMissingFeature; 2939 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature, 2940 MatchingInlineAsm); 2941 } 2942 2943 // If one instruction matched with an invalid operand, report this as an 2944 // operand failure. 2945 if (std::count(std::begin(Match), std::end(Match), 2946 Match_InvalidOperand) == 1) { 2947 return Error(IDLoc, "invalid operand for instruction", EmptyRange, 2948 MatchingInlineAsm); 2949 } 2950 2951 // If all of these were an outright failure, report it in a useless way. 2952 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix", 2953 EmptyRange, MatchingInlineAsm); 2954 return true; 2955 } 2956 2957 bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode, 2958 OperandVector &Operands, 2959 MCStreamer &Out, 2960 uint64_t &ErrorInfo, 2961 bool MatchingInlineAsm) { 2962 assert(!Operands.empty() && "Unexpect empty operand list!"); 2963 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]); 2964 assert(Op.isToken() && "Leading operand should always be a mnemonic!"); 2965 StringRef Mnemonic = Op.getToken(); 2966 SMRange EmptyRange = None; 2967 StringRef Base = Op.getToken(); 2968 unsigned Prefixes = getPrefixes(Operands); 2969 2970 // First, handle aliases that expand to multiple instructions. 2971 MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm); 2972 2973 MCInst Inst; 2974 2975 if (Prefixes) 2976 Inst.setFlags(Prefixes); 2977 2978 // Find one unsized memory operand, if present. 2979 X86Operand *UnsizedMemOp = nullptr; 2980 for (const auto &Op : Operands) { 2981 X86Operand *X86Op = static_cast<X86Operand *>(Op.get()); 2982 if (X86Op->isMemUnsized()) { 2983 UnsizedMemOp = X86Op; 2984 // Have we found an unqualified memory operand, 2985 // break. IA allows only one memory operand. 2986 break; 2987 } 2988 } 2989 2990 // Allow some instructions to have implicitly pointer-sized operands. This is 2991 // compatible with gas. 2992 if (UnsizedMemOp) { 2993 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"}; 2994 for (const char *Instr : PtrSizedInstrs) { 2995 if (Mnemonic == Instr) { 2996 UnsizedMemOp->Mem.Size = getPointerWidth(); 2997 break; 2998 } 2999 } 3000 } 3001 3002 SmallVector<unsigned, 8> Match; 3003 uint64_t ErrorInfoMissingFeature = 0; 3004 3005 // If unsized push has immediate operand we should default the default pointer 3006 // size for the size. 3007 if (Mnemonic == "push" && Operands.size() == 2) { 3008 auto *X86Op = static_cast<X86Operand *>(Operands[1].get()); 3009 if (X86Op->isImm()) { 3010 // If it's not a constant fall through and let remainder take care of it. 3011 const auto *CE = dyn_cast<MCConstantExpr>(X86Op->getImm()); 3012 unsigned Size = getPointerWidth(); 3013 if (CE && 3014 (isIntN(Size, CE->getValue()) || isUIntN(Size, CE->getValue()))) { 3015 SmallString<16> Tmp; 3016 Tmp += Base; 3017 Tmp += (is64BitMode()) 3018 ? "q" 3019 : (is32BitMode()) ? "l" : (is16BitMode()) ? "w" : " "; 3020 Op.setTokenValue(Tmp); 3021 // Do match in ATT mode to allow explicit suffix usage. 3022 Match.push_back(MatchInstruction(Operands, Inst, ErrorInfo, 3023 MatchingInlineAsm, 3024 false /*isParsingIntelSyntax()*/)); 3025 Op.setTokenValue(Base); 3026 } 3027 } 3028 } 3029 3030 // If an unsized memory operand is present, try to match with each memory 3031 // operand size. In Intel assembly, the size is not part of the instruction 3032 // mnemonic. 3033 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) { 3034 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512}; 3035 for (unsigned Size : MopSizes) { 3036 UnsizedMemOp->Mem.Size = Size; 3037 uint64_t ErrorInfoIgnore; 3038 unsigned LastOpcode = Inst.getOpcode(); 3039 unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore, 3040 MatchingInlineAsm, isParsingIntelSyntax()); 3041 if (Match.empty() || LastOpcode != Inst.getOpcode()) 3042 Match.push_back(M); 3043 3044 // If this returned as a missing feature failure, remember that. 3045 if (Match.back() == Match_MissingFeature) 3046 ErrorInfoMissingFeature = ErrorInfoIgnore; 3047 } 3048 3049 // Restore the size of the unsized memory operand if we modified it. 3050 UnsizedMemOp->Mem.Size = 0; 3051 } 3052 3053 // If we haven't matched anything yet, this is not a basic integer or FPU 3054 // operation. There shouldn't be any ambiguity in our mnemonic table, so try 3055 // matching with the unsized operand. 3056 if (Match.empty()) { 3057 Match.push_back(MatchInstruction( 3058 Operands, Inst, ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax())); 3059 // If this returned as a missing feature failure, remember that. 3060 if (Match.back() == Match_MissingFeature) 3061 ErrorInfoMissingFeature = ErrorInfo; 3062 } 3063 3064 // Restore the size of the unsized memory operand if we modified it. 3065 if (UnsizedMemOp) 3066 UnsizedMemOp->Mem.Size = 0; 3067 3068 // If it's a bad mnemonic, all results will be the same. 3069 if (Match.back() == Match_MnemonicFail) { 3070 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'", 3071 Op.getLocRange(), MatchingInlineAsm); 3072 } 3073 3074 unsigned NumSuccessfulMatches = 3075 std::count(std::begin(Match), std::end(Match), Match_Success); 3076 3077 // If matching was ambiguous and we had size information from the frontend, 3078 // try again with that. This handles cases like "movxz eax, m8/m16". 3079 if (UnsizedMemOp && NumSuccessfulMatches > 1 && 3080 UnsizedMemOp->getMemFrontendSize()) { 3081 UnsizedMemOp->Mem.Size = UnsizedMemOp->getMemFrontendSize(); 3082 unsigned M = MatchInstruction( 3083 Operands, Inst, ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax()); 3084 if (M == Match_Success) 3085 NumSuccessfulMatches = 1; 3086 3087 // Add a rewrite that encodes the size information we used from the 3088 // frontend. 3089 InstInfo->AsmRewrites->emplace_back( 3090 AOK_SizeDirective, UnsizedMemOp->getStartLoc(), 3091 /*Len=*/0, UnsizedMemOp->getMemFrontendSize()); 3092 } 3093 3094 // If exactly one matched, then we treat that as a successful match (and the 3095 // instruction will already have been filled in correctly, since the failing 3096 // matches won't have modified it). 3097 if (NumSuccessfulMatches == 1) { 3098 if (!MatchingInlineAsm && validateInstruction(Inst, Operands)) 3099 return true; 3100 // Some instructions need post-processing to, for example, tweak which 3101 // encoding is selected. Loop on it while changes happen so the individual 3102 // transformations can chain off each other. 3103 if (!MatchingInlineAsm) 3104 while (processInstruction(Inst, Operands)) 3105 ; 3106 Inst.setLoc(IDLoc); 3107 if (!MatchingInlineAsm) 3108 EmitInstruction(Inst, Operands, Out); 3109 Opcode = Inst.getOpcode(); 3110 return false; 3111 } else if (NumSuccessfulMatches > 1) { 3112 assert(UnsizedMemOp && 3113 "multiple matches only possible with unsized memory operands"); 3114 return Error(UnsizedMemOp->getStartLoc(), 3115 "ambiguous operand size for instruction '" + Mnemonic + "\'", 3116 UnsizedMemOp->getLocRange()); 3117 } 3118 3119 // If one instruction matched with a missing feature, report this as a 3120 // missing feature. 3121 if (std::count(std::begin(Match), std::end(Match), 3122 Match_MissingFeature) == 1) { 3123 ErrorInfo = ErrorInfoMissingFeature; 3124 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeature, 3125 MatchingInlineAsm); 3126 } 3127 3128 // If one instruction matched with an invalid operand, report this as an 3129 // operand failure. 3130 if (std::count(std::begin(Match), std::end(Match), 3131 Match_InvalidOperand) == 1) { 3132 return Error(IDLoc, "invalid operand for instruction", EmptyRange, 3133 MatchingInlineAsm); 3134 } 3135 3136 // If all of these were an outright failure, report it in a useless way. 3137 return Error(IDLoc, "unknown instruction mnemonic", EmptyRange, 3138 MatchingInlineAsm); 3139 } 3140 3141 bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) { 3142 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo); 3143 } 3144 3145 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) { 3146 MCAsmParser &Parser = getParser(); 3147 StringRef IDVal = DirectiveID.getIdentifier(); 3148 if (IDVal == ".word") 3149 return ParseDirectiveWord(2, DirectiveID.getLoc()); 3150 else if (IDVal.startswith(".code")) 3151 return ParseDirectiveCode(IDVal, DirectiveID.getLoc()); 3152 else if (IDVal.startswith(".att_syntax")) { 3153 getParser().setParsingInlineAsm(false); 3154 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3155 if (Parser.getTok().getString() == "prefix") 3156 Parser.Lex(); 3157 else if (Parser.getTok().getString() == "noprefix") 3158 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not " 3159 "supported: registers must have a " 3160 "'%' prefix in .att_syntax"); 3161 } 3162 getParser().setAssemblerDialect(0); 3163 return false; 3164 } else if (IDVal.startswith(".intel_syntax")) { 3165 getParser().setAssemblerDialect(1); 3166 getParser().setParsingInlineAsm(true); 3167 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3168 if (Parser.getTok().getString() == "noprefix") 3169 Parser.Lex(); 3170 else if (Parser.getTok().getString() == "prefix") 3171 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not " 3172 "supported: registers must not have " 3173 "a '%' prefix in .intel_syntax"); 3174 } 3175 return false; 3176 } else if (IDVal == ".even") 3177 return parseDirectiveEven(DirectiveID.getLoc()); 3178 else if (IDVal == ".cv_fpo_proc") 3179 return parseDirectiveFPOProc(DirectiveID.getLoc()); 3180 else if (IDVal == ".cv_fpo_setframe") 3181 return parseDirectiveFPOSetFrame(DirectiveID.getLoc()); 3182 else if (IDVal == ".cv_fpo_pushreg") 3183 return parseDirectiveFPOPushReg(DirectiveID.getLoc()); 3184 else if (IDVal == ".cv_fpo_stackalloc") 3185 return parseDirectiveFPOStackAlloc(DirectiveID.getLoc()); 3186 else if (IDVal == ".cv_fpo_endprologue") 3187 return parseDirectiveFPOEndPrologue(DirectiveID.getLoc()); 3188 else if (IDVal == ".cv_fpo_endproc") 3189 return parseDirectiveFPOEndProc(DirectiveID.getLoc()); 3190 3191 return true; 3192 } 3193 3194 /// parseDirectiveEven 3195 /// ::= .even 3196 bool X86AsmParser::parseDirectiveEven(SMLoc L) { 3197 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3198 TokError("unexpected token in directive"); 3199 return false; 3200 } 3201 const MCSection *Section = getStreamer().getCurrentSectionOnly(); 3202 if (!Section) { 3203 getStreamer().InitSections(false); 3204 Section = getStreamer().getCurrentSectionOnly(); 3205 } 3206 if (Section->UseCodeAlign()) 3207 getStreamer().EmitCodeAlignment(2, 0); 3208 else 3209 getStreamer().EmitValueToAlignment(2, 0, 1, 0); 3210 return false; 3211 } 3212 /// ParseDirectiveWord 3213 /// ::= .word [ expression (, expression)* ] 3214 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 3215 MCAsmParser &Parser = getParser(); 3216 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3217 for (;;) { 3218 const MCExpr *Value; 3219 SMLoc ExprLoc = getLexer().getLoc(); 3220 if (getParser().parseExpression(Value)) 3221 return false; 3222 3223 if (const auto *MCE = dyn_cast<MCConstantExpr>(Value)) { 3224 assert(Size <= 8 && "Invalid size"); 3225 uint64_t IntValue = MCE->getValue(); 3226 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue)) 3227 return Error(ExprLoc, "literal value out of range for directive"); 3228 getStreamer().EmitIntValue(IntValue, Size); 3229 } else { 3230 getStreamer().EmitValue(Value, Size, ExprLoc); 3231 } 3232 3233 if (getLexer().is(AsmToken::EndOfStatement)) 3234 break; 3235 3236 // FIXME: Improve diagnostic. 3237 if (getLexer().isNot(AsmToken::Comma)) { 3238 Error(L, "unexpected token in directive"); 3239 return false; 3240 } 3241 Parser.Lex(); 3242 } 3243 } 3244 3245 Parser.Lex(); 3246 return false; 3247 } 3248 3249 /// ParseDirectiveCode 3250 /// ::= .code16 | .code32 | .code64 3251 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) { 3252 MCAsmParser &Parser = getParser(); 3253 Code16GCC = false; 3254 if (IDVal == ".code16") { 3255 Parser.Lex(); 3256 if (!is16BitMode()) { 3257 SwitchMode(X86::Mode16Bit); 3258 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 3259 } 3260 } else if (IDVal == ".code16gcc") { 3261 // .code16gcc parses as if in 32-bit mode, but emits code in 16-bit mode. 3262 Parser.Lex(); 3263 Code16GCC = true; 3264 if (!is16BitMode()) { 3265 SwitchMode(X86::Mode16Bit); 3266 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 3267 } 3268 } else if (IDVal == ".code32") { 3269 Parser.Lex(); 3270 if (!is32BitMode()) { 3271 SwitchMode(X86::Mode32Bit); 3272 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 3273 } 3274 } else if (IDVal == ".code64") { 3275 Parser.Lex(); 3276 if (!is64BitMode()) { 3277 SwitchMode(X86::Mode64Bit); 3278 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64); 3279 } 3280 } else { 3281 Error(L, "unknown directive " + IDVal); 3282 return false; 3283 } 3284 3285 return false; 3286 } 3287 3288 // .cv_fpo_proc foo 3289 bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) { 3290 MCAsmParser &Parser = getParser(); 3291 StringRef ProcName; 3292 int64_t ParamsSize; 3293 if (Parser.parseIdentifier(ProcName)) 3294 return Parser.TokError("expected symbol name"); 3295 if (Parser.parseIntToken(ParamsSize, "expected parameter byte count")) 3296 return true; 3297 if (!isUIntN(32, ParamsSize)) 3298 return Parser.TokError("parameters size out of range"); 3299 if (Parser.parseEOL("unexpected tokens")) 3300 return addErrorSuffix(" in '.cv_fpo_proc' directive"); 3301 MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName); 3302 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L); 3303 } 3304 3305 // .cv_fpo_setframe ebp 3306 bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) { 3307 MCAsmParser &Parser = getParser(); 3308 unsigned Reg; 3309 SMLoc DummyLoc; 3310 if (ParseRegister(Reg, DummyLoc, DummyLoc) || 3311 Parser.parseEOL("unexpected tokens")) 3312 return addErrorSuffix(" in '.cv_fpo_setframe' directive"); 3313 return getTargetStreamer().emitFPOSetFrame(Reg, L); 3314 } 3315 3316 // .cv_fpo_pushreg ebx 3317 bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) { 3318 MCAsmParser &Parser = getParser(); 3319 unsigned Reg; 3320 SMLoc DummyLoc; 3321 if (ParseRegister(Reg, DummyLoc, DummyLoc) || 3322 Parser.parseEOL("unexpected tokens")) 3323 return addErrorSuffix(" in '.cv_fpo_pushreg' directive"); 3324 return getTargetStreamer().emitFPOPushReg(Reg, L); 3325 } 3326 3327 // .cv_fpo_stackalloc 20 3328 bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) { 3329 MCAsmParser &Parser = getParser(); 3330 int64_t Offset; 3331 if (Parser.parseIntToken(Offset, "expected offset") || 3332 Parser.parseEOL("unexpected tokens")) 3333 return addErrorSuffix(" in '.cv_fpo_stackalloc' directive"); 3334 return getTargetStreamer().emitFPOStackAlloc(Offset, L); 3335 } 3336 3337 // .cv_fpo_endprologue 3338 bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) { 3339 MCAsmParser &Parser = getParser(); 3340 if (Parser.parseEOL("unexpected tokens")) 3341 return addErrorSuffix(" in '.cv_fpo_endprologue' directive"); 3342 return getTargetStreamer().emitFPOEndPrologue(L); 3343 } 3344 3345 // .cv_fpo_endproc 3346 bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) { 3347 MCAsmParser &Parser = getParser(); 3348 if (Parser.parseEOL("unexpected tokens")) 3349 return addErrorSuffix(" in '.cv_fpo_endproc' directive"); 3350 return getTargetStreamer().emitFPOEndProc(L); 3351 } 3352 3353 // Force static initialization. 3354 extern "C" void LLVMInitializeX86AsmParser() { 3355 RegisterMCAsmParser<X86AsmParser> X(getTheX86_32Target()); 3356 RegisterMCAsmParser<X86AsmParser> Y(getTheX86_64Target()); 3357 } 3358 3359 #define GET_REGISTER_MATCHER 3360 #define GET_MATCHER_IMPLEMENTATION 3361 #define GET_SUBTARGET_FEATURE_NAME 3362 #include "X86GenAsmMatcher.inc" 3363