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