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