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