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