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