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