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