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