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