brintos

brintos / llvm-project-archived public Read only

0
0
Text · 180.1 KiB · bac3692 Raw
5111 lines · cpp
1//===-- X86AsmParser.cpp - Parse X86 assembly to MCInst instructions ------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "MCTargetDesc/X86BaseInfo.h"10#include "MCTargetDesc/X86EncodingOptimization.h"11#include "MCTargetDesc/X86IntelInstPrinter.h"12#include "MCTargetDesc/X86MCAsmInfo.h"13#include "MCTargetDesc/X86MCExpr.h"14#include "MCTargetDesc/X86MCTargetDesc.h"15#include "MCTargetDesc/X86TargetStreamer.h"16#include "TargetInfo/X86TargetInfo.h"17#include "X86Operand.h"18#include "X86RegisterInfo.h"19#include "llvm-c/Visibility.h"20#include "llvm/ADT/STLExtras.h"21#include "llvm/ADT/SmallString.h"22#include "llvm/ADT/SmallVector.h"23#include "llvm/ADT/StringRef.h"24#include "llvm/ADT/StringSwitch.h"25#include "llvm/ADT/Twine.h"26#include "llvm/MC/MCContext.h"27#include "llvm/MC/MCExpr.h"28#include "llvm/MC/MCInst.h"29#include "llvm/MC/MCInstrInfo.h"30#include "llvm/MC/MCParser/AsmLexer.h"31#include "llvm/MC/MCParser/MCAsmParser.h"32#include "llvm/MC/MCParser/MCParsedAsmOperand.h"33#include "llvm/MC/MCParser/MCTargetAsmParser.h"34#include "llvm/MC/MCRegister.h"35#include "llvm/MC/MCRegisterInfo.h"36#include "llvm/MC/MCSection.h"37#include "llvm/MC/MCStreamer.h"38#include "llvm/MC/MCSubtargetInfo.h"39#include "llvm/MC/MCSymbol.h"40#include "llvm/MC/TargetRegistry.h"41#include "llvm/Support/CommandLine.h"42#include "llvm/Support/Compiler.h"43#include "llvm/Support/SourceMgr.h"44#include "llvm/Support/raw_ostream.h"45#include <algorithm>46#include <cstdint>47#include <memory>48 49using namespace llvm;50 51static cl::opt<bool> LVIInlineAsmHardening(52    "x86-experimental-lvi-inline-asm-hardening",53    cl::desc("Harden inline assembly code that may be vulnerable to Load Value"54             " Injection (LVI). This feature is experimental."), cl::Hidden);55 56static bool checkScale(unsigned Scale, StringRef &ErrMsg) {57  if (Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {58    ErrMsg = "scale factor in address must be 1, 2, 4 or 8";59    return true;60  }61  return false;62}63 64namespace {65 66// Including the generated SSE2AVX compression tables.67#define GET_X86_SSE2AVX_TABLE68#include "X86GenInstrMapping.inc"69 70static const char OpPrecedence[] = {71    0,  // IC_OR72    1,  // IC_XOR73    2,  // IC_AND74    4,  // IC_LSHIFT75    4,  // IC_RSHIFT76    5,  // IC_PLUS77    5,  // IC_MINUS78    6,  // IC_MULTIPLY79    6,  // IC_DIVIDE80    6,  // IC_MOD81    7,  // IC_NOT82    8,  // IC_NEG83    9,  // IC_RPAREN84    10, // IC_LPAREN85    0,  // IC_IMM86    0,  // IC_REGISTER87    3,  // IC_EQ88    3,  // IC_NE89    3,  // IC_LT90    3,  // IC_LE91    3,  // IC_GT92    3   // IC_GE93};94 95class X86AsmParser : public MCTargetAsmParser {96  ParseInstructionInfo *InstInfo;97  bool Code16GCC;98  unsigned ForcedDataPrefix = 0;99 100  enum OpcodePrefix {101    OpcodePrefix_Default,102    OpcodePrefix_REX,103    OpcodePrefix_REX2,104    OpcodePrefix_VEX,105    OpcodePrefix_VEX2,106    OpcodePrefix_VEX3,107    OpcodePrefix_EVEX,108  };109 110  OpcodePrefix ForcedOpcodePrefix = OpcodePrefix_Default;111 112  enum DispEncoding {113    DispEncoding_Default,114    DispEncoding_Disp8,115    DispEncoding_Disp32,116  };117 118  DispEncoding ForcedDispEncoding = DispEncoding_Default;119 120  // Does this instruction use apx extended register?121  bool UseApxExtendedReg = false;122  // Is this instruction explicitly required not to update flags?123  bool ForcedNoFlag = false;124 125private:126  SMLoc consumeToken() {127    MCAsmParser &Parser = getParser();128    SMLoc Result = Parser.getTok().getLoc();129    Parser.Lex();130    return Result;131  }132 133  bool tokenIsStartOfStatement(AsmToken::TokenKind Token) override {134    return Token == AsmToken::LCurly;135  }136 137  X86TargetStreamer &getTargetStreamer() {138    assert(getParser().getStreamer().getTargetStreamer() &&139           "do not have a target streamer");140    MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();141    return static_cast<X86TargetStreamer &>(TS);142  }143 144  unsigned MatchInstruction(const OperandVector &Operands, MCInst &Inst,145                            uint64_t &ErrorInfo, FeatureBitset &MissingFeatures,146                            bool matchingInlineAsm, unsigned VariantID = 0) {147    // In Code16GCC mode, match as 32-bit.148    if (Code16GCC)149      SwitchMode(X86::Is32Bit);150    unsigned rv = MatchInstructionImpl(Operands, Inst, ErrorInfo,151                                       MissingFeatures, matchingInlineAsm,152                                       VariantID);153    if (Code16GCC)154      SwitchMode(X86::Is16Bit);155    return rv;156  }157 158  enum InfixCalculatorTok {159    IC_OR = 0,160    IC_XOR,161    IC_AND,162    IC_LSHIFT,163    IC_RSHIFT,164    IC_PLUS,165    IC_MINUS,166    IC_MULTIPLY,167    IC_DIVIDE,168    IC_MOD,169    IC_NOT,170    IC_NEG,171    IC_RPAREN,172    IC_LPAREN,173    IC_IMM,174    IC_REGISTER,175    IC_EQ,176    IC_NE,177    IC_LT,178    IC_LE,179    IC_GT,180    IC_GE181  };182 183  enum IntelOperatorKind {184    IOK_INVALID = 0,185    IOK_LENGTH,186    IOK_SIZE,187    IOK_TYPE,188  };189 190  enum MasmOperatorKind {191    MOK_INVALID = 0,192    MOK_LENGTHOF,193    MOK_SIZEOF,194    MOK_TYPE,195  };196 197  class InfixCalculator {198    typedef std::pair< InfixCalculatorTok, int64_t > ICToken;199    SmallVector<InfixCalculatorTok, 4> InfixOperatorStack;200    SmallVector<ICToken, 4> PostfixStack;201 202    bool isUnaryOperator(InfixCalculatorTok Op) const {203      return Op == IC_NEG || Op == IC_NOT;204    }205 206  public:207    int64_t popOperand() {208      assert (!PostfixStack.empty() && "Poped an empty stack!");209      ICToken Op = PostfixStack.pop_back_val();210      if (!(Op.first == IC_IMM || Op.first == IC_REGISTER))211        return -1; // The invalid Scale value will be caught later by checkScale212      return Op.second;213    }214    void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) {215      assert ((Op == IC_IMM || Op == IC_REGISTER) &&216              "Unexpected operand!");217      PostfixStack.push_back(std::make_pair(Op, Val));218    }219 220    void popOperator() { InfixOperatorStack.pop_back(); }221    void pushOperator(InfixCalculatorTok Op) {222      // Push the new operator if the stack is empty.223      if (InfixOperatorStack.empty()) {224        InfixOperatorStack.push_back(Op);225        return;226      }227 228      // Push the new operator if it has a higher precedence than the operator229      // on the top of the stack or the operator on the top of the stack is a230      // left parentheses.231      unsigned Idx = InfixOperatorStack.size() - 1;232      InfixCalculatorTok StackOp = InfixOperatorStack[Idx];233      if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {234        InfixOperatorStack.push_back(Op);235        return;236      }237 238      // The operator on the top of the stack has higher precedence than the239      // new operator.240      unsigned ParenCount = 0;241      while (true) {242        // Nothing to process.243        if (InfixOperatorStack.empty())244          break;245 246        Idx = InfixOperatorStack.size() - 1;247        StackOp = InfixOperatorStack[Idx];248        if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount))249          break;250 251        // If we have an even parentheses count and we see a left parentheses,252        // then stop processing.253        if (!ParenCount && StackOp == IC_LPAREN)254          break;255 256        if (StackOp == IC_RPAREN) {257          ++ParenCount;258          InfixOperatorStack.pop_back();259        } else if (StackOp == IC_LPAREN) {260          --ParenCount;261          InfixOperatorStack.pop_back();262        } else {263          InfixOperatorStack.pop_back();264          PostfixStack.push_back(std::make_pair(StackOp, 0));265        }266      }267      // Push the new operator.268      InfixOperatorStack.push_back(Op);269    }270 271    int64_t execute() {272      // Push any remaining operators onto the postfix stack.273      while (!InfixOperatorStack.empty()) {274        InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();275        if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)276          PostfixStack.push_back(std::make_pair(StackOp, 0));277      }278 279      if (PostfixStack.empty())280        return 0;281 282      SmallVector<ICToken, 16> OperandStack;283      for (const ICToken &Op : PostfixStack) {284        if (Op.first == IC_IMM || Op.first == IC_REGISTER) {285          OperandStack.push_back(Op);286        } else if (isUnaryOperator(Op.first)) {287          assert (OperandStack.size() > 0 && "Too few operands.");288          ICToken Operand = OperandStack.pop_back_val();289          assert (Operand.first == IC_IMM &&290                  "Unary operation with a register!");291          switch (Op.first) {292          default:293            report_fatal_error("Unexpected operator!");294            break;295          case IC_NEG:296            OperandStack.push_back(std::make_pair(IC_IMM, -Operand.second));297            break;298          case IC_NOT:299            OperandStack.push_back(std::make_pair(IC_IMM, ~Operand.second));300            break;301          }302        } else {303          assert (OperandStack.size() > 1 && "Too few operands.");304          int64_t Val;305          ICToken Op2 = OperandStack.pop_back_val();306          ICToken Op1 = OperandStack.pop_back_val();307          switch (Op.first) {308          default:309            report_fatal_error("Unexpected operator!");310            break;311          case IC_PLUS:312            Val = Op1.second + Op2.second;313            OperandStack.push_back(std::make_pair(IC_IMM, Val));314            break;315          case IC_MINUS:316            Val = Op1.second - Op2.second;317            OperandStack.push_back(std::make_pair(IC_IMM, Val));318            break;319          case IC_MULTIPLY:320            assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&321                    "Multiply operation with an immediate and a register!");322            Val = Op1.second * Op2.second;323            OperandStack.push_back(std::make_pair(IC_IMM, Val));324            break;325          case IC_DIVIDE:326            assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&327                    "Divide operation with an immediate and a register!");328            assert (Op2.second != 0 && "Division by zero!");329            Val = Op1.second / Op2.second;330            OperandStack.push_back(std::make_pair(IC_IMM, Val));331            break;332          case IC_MOD:333            assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&334                    "Modulo operation with an immediate and a register!");335            Val = Op1.second % Op2.second;336            OperandStack.push_back(std::make_pair(IC_IMM, Val));337            break;338          case IC_OR:339            assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&340                    "Or operation with an immediate and a register!");341            Val = Op1.second | Op2.second;342            OperandStack.push_back(std::make_pair(IC_IMM, Val));343            break;344          case IC_XOR:345            assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&346              "Xor operation with an immediate and a register!");347            Val = Op1.second ^ Op2.second;348            OperandStack.push_back(std::make_pair(IC_IMM, Val));349            break;350          case IC_AND:351            assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&352                    "And operation with an immediate and a register!");353            Val = Op1.second & Op2.second;354            OperandStack.push_back(std::make_pair(IC_IMM, Val));355            break;356          case IC_LSHIFT:357            assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&358                    "Left shift operation with an immediate and a register!");359            Val = Op1.second << Op2.second;360            OperandStack.push_back(std::make_pair(IC_IMM, Val));361            break;362          case IC_RSHIFT:363            assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&364                    "Right shift operation with an immediate and a register!");365            Val = Op1.second >> Op2.second;366            OperandStack.push_back(std::make_pair(IC_IMM, Val));367            break;368          case IC_EQ:369            assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&370                   "Equals operation with an immediate and a register!");371            Val = (Op1.second == Op2.second) ? -1 : 0;372            OperandStack.push_back(std::make_pair(IC_IMM, Val));373            break;374          case IC_NE:375            assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&376                   "Not-equals operation with an immediate and a register!");377            Val = (Op1.second != Op2.second) ? -1 : 0;378            OperandStack.push_back(std::make_pair(IC_IMM, Val));379            break;380          case IC_LT:381            assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&382                   "Less-than operation with an immediate and a register!");383            Val = (Op1.second < Op2.second) ? -1 : 0;384            OperandStack.push_back(std::make_pair(IC_IMM, Val));385            break;386          case IC_LE:387            assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&388                   "Less-than-or-equal operation with an immediate and a "389                   "register!");390            Val = (Op1.second <= Op2.second) ? -1 : 0;391            OperandStack.push_back(std::make_pair(IC_IMM, Val));392            break;393          case IC_GT:394            assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&395                   "Greater-than operation with an immediate and a register!");396            Val = (Op1.second > Op2.second) ? -1 : 0;397            OperandStack.push_back(std::make_pair(IC_IMM, Val));398            break;399          case IC_GE:400            assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&401                   "Greater-than-or-equal operation with an immediate and a "402                   "register!");403            Val = (Op1.second >= Op2.second) ? -1 : 0;404            OperandStack.push_back(std::make_pair(IC_IMM, Val));405            break;406          }407        }408      }409      assert (OperandStack.size() == 1 && "Expected a single result.");410      return OperandStack.pop_back_val().second;411    }412  };413 414  enum IntelExprState {415    IES_INIT,416    IES_OR,417    IES_XOR,418    IES_AND,419    IES_EQ,420    IES_NE,421    IES_LT,422    IES_LE,423    IES_GT,424    IES_GE,425    IES_LSHIFT,426    IES_RSHIFT,427    IES_PLUS,428    IES_MINUS,429    IES_OFFSET,430    IES_CAST,431    IES_NOT,432    IES_MULTIPLY,433    IES_DIVIDE,434    IES_MOD,435    IES_LBRAC,436    IES_RBRAC,437    IES_LPAREN,438    IES_RPAREN,439    IES_REGISTER,440    IES_INTEGER,441    IES_ERROR442  };443 444  class IntelExprStateMachine {445    IntelExprState State = IES_INIT, PrevState = IES_ERROR;446    MCRegister BaseReg, IndexReg, TmpReg;447    unsigned Scale = 0;448    int64_t Imm = 0;449    const MCExpr *Sym = nullptr;450    StringRef SymName;451    InfixCalculator IC;452    InlineAsmIdentifierInfo Info;453    short BracCount = 0;454    bool MemExpr = false;455    bool BracketUsed = false;456    bool OffsetOperator = false;457    bool AttachToOperandIdx = false;458    bool IsPIC = false;459    SMLoc OffsetOperatorLoc;460    AsmTypeInfo CurType;461 462    bool setSymRef(const MCExpr *Val, StringRef ID, StringRef &ErrMsg) {463      if (Sym) {464        ErrMsg = "cannot use more than one symbol in memory operand";465        return true;466      }467      Sym = Val;468      SymName = ID;469      return false;470    }471 472  public:473    IntelExprStateMachine() = default;474 475    void addImm(int64_t imm) { Imm += imm; }476    short getBracCount() const { return BracCount; }477    bool isMemExpr() const { return MemExpr; }478    bool isBracketUsed() const { return BracketUsed; }479    bool isOffsetOperator() const { return OffsetOperator; }480    SMLoc getOffsetLoc() const { return OffsetOperatorLoc; }481    MCRegister getBaseReg() const { return BaseReg; }482    MCRegister getIndexReg() const { return IndexReg; }483    unsigned getScale() const { return Scale; }484    const MCExpr *getSym() const { return Sym; }485    StringRef getSymName() const { return SymName; }486    StringRef getType() const { return CurType.Name; }487    unsigned getSize() const { return CurType.Size; }488    unsigned getElementSize() const { return CurType.ElementSize; }489    unsigned getLength() const { return CurType.Length; }490    int64_t getImm() { return Imm + IC.execute(); }491    bool isValidEndState() const {492      return State == IES_RBRAC || State == IES_RPAREN ||493             State == IES_INTEGER || State == IES_REGISTER ||494             State == IES_OFFSET;495    }496 497    // Is the intel expression appended after an operand index.498    // [OperandIdx][Intel Expression]499    // This is neccessary for checking if it is an independent500    // intel expression at back end when parse inline asm.501    void setAppendAfterOperand() { AttachToOperandIdx = true; }502 503    bool isPIC() const { return IsPIC; }504    void setPIC() { IsPIC = true; }505 506    bool hadError() const { return State == IES_ERROR; }507    const InlineAsmIdentifierInfo &getIdentifierInfo() const { return Info; }508 509    bool regsUseUpError(StringRef &ErrMsg) {510      // This case mostly happen in inline asm, e.g. Arr[BaseReg + IndexReg]511      // can not intruduce additional register in inline asm in PIC model.512      if (IsPIC && AttachToOperandIdx)513        ErrMsg = "Don't use 2 or more regs for mem offset in PIC model!";514      else515        ErrMsg = "BaseReg/IndexReg already set!";516      return true;517    }518 519    void onOr() {520      IntelExprState CurrState = State;521      switch (State) {522      default:523        State = IES_ERROR;524        break;525      case IES_INTEGER:526      case IES_RPAREN:527      case IES_REGISTER:528        State = IES_OR;529        IC.pushOperator(IC_OR);530        break;531      }532      PrevState = CurrState;533    }534    void onXor() {535      IntelExprState CurrState = State;536      switch (State) {537      default:538        State = IES_ERROR;539        break;540      case IES_INTEGER:541      case IES_RPAREN:542      case IES_REGISTER:543        State = IES_XOR;544        IC.pushOperator(IC_XOR);545        break;546      }547      PrevState = CurrState;548    }549    void onAnd() {550      IntelExprState CurrState = State;551      switch (State) {552      default:553        State = IES_ERROR;554        break;555      case IES_INTEGER:556      case IES_RPAREN:557      case IES_REGISTER:558        State = IES_AND;559        IC.pushOperator(IC_AND);560        break;561      }562      PrevState = CurrState;563    }564    void onEq() {565      IntelExprState CurrState = State;566      switch (State) {567      default:568        State = IES_ERROR;569        break;570      case IES_INTEGER:571      case IES_RPAREN:572      case IES_REGISTER:573        State = IES_EQ;574        IC.pushOperator(IC_EQ);575        break;576      }577      PrevState = CurrState;578    }579    void onNE() {580      IntelExprState CurrState = State;581      switch (State) {582      default:583        State = IES_ERROR;584        break;585      case IES_INTEGER:586      case IES_RPAREN:587      case IES_REGISTER:588        State = IES_NE;589        IC.pushOperator(IC_NE);590        break;591      }592      PrevState = CurrState;593    }594    void onLT() {595      IntelExprState CurrState = State;596      switch (State) {597      default:598        State = IES_ERROR;599        break;600      case IES_INTEGER:601      case IES_RPAREN:602      case IES_REGISTER:603        State = IES_LT;604        IC.pushOperator(IC_LT);605        break;606      }607      PrevState = CurrState;608    }609    void onLE() {610      IntelExprState CurrState = State;611      switch (State) {612      default:613        State = IES_ERROR;614        break;615      case IES_INTEGER:616      case IES_RPAREN:617      case IES_REGISTER:618        State = IES_LE;619        IC.pushOperator(IC_LE);620        break;621      }622      PrevState = CurrState;623    }624    void onGT() {625      IntelExprState CurrState = State;626      switch (State) {627      default:628        State = IES_ERROR;629        break;630      case IES_INTEGER:631      case IES_RPAREN:632      case IES_REGISTER:633        State = IES_GT;634        IC.pushOperator(IC_GT);635        break;636      }637      PrevState = CurrState;638    }639    void onGE() {640      IntelExprState CurrState = State;641      switch (State) {642      default:643        State = IES_ERROR;644        break;645      case IES_INTEGER:646      case IES_RPAREN:647      case IES_REGISTER:648        State = IES_GE;649        IC.pushOperator(IC_GE);650        break;651      }652      PrevState = CurrState;653    }654    void onLShift() {655      IntelExprState CurrState = State;656      switch (State) {657      default:658        State = IES_ERROR;659        break;660      case IES_INTEGER:661      case IES_RPAREN:662      case IES_REGISTER:663        State = IES_LSHIFT;664        IC.pushOperator(IC_LSHIFT);665        break;666      }667      PrevState = CurrState;668    }669    void onRShift() {670      IntelExprState CurrState = State;671      switch (State) {672      default:673        State = IES_ERROR;674        break;675      case IES_INTEGER:676      case IES_RPAREN:677      case IES_REGISTER:678        State = IES_RSHIFT;679        IC.pushOperator(IC_RSHIFT);680        break;681      }682      PrevState = CurrState;683    }684    bool onPlus(StringRef &ErrMsg) {685      IntelExprState CurrState = State;686      switch (State) {687      default:688        State = IES_ERROR;689        break;690      case IES_INTEGER:691      case IES_RPAREN:692      case IES_REGISTER:693      case IES_OFFSET:694        State = IES_PLUS;695        IC.pushOperator(IC_PLUS);696        if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {697          // If we already have a BaseReg, then assume this is the IndexReg with698          // no explicit scale.699          if (!BaseReg) {700            BaseReg = TmpReg;701          } else {702            if (IndexReg)703              return regsUseUpError(ErrMsg);704            IndexReg = TmpReg;705            Scale = 0;706          }707        }708        break;709      }710      PrevState = CurrState;711      return false;712    }713    bool onMinus(StringRef &ErrMsg) {714      IntelExprState CurrState = State;715      switch (State) {716      default:717        State = IES_ERROR;718        break;719      case IES_OR:720      case IES_XOR:721      case IES_AND:722      case IES_EQ:723      case IES_NE:724      case IES_LT:725      case IES_LE:726      case IES_GT:727      case IES_GE:728      case IES_LSHIFT:729      case IES_RSHIFT:730      case IES_PLUS:731      case IES_NOT:732      case IES_MULTIPLY:733      case IES_DIVIDE:734      case IES_MOD:735      case IES_LPAREN:736      case IES_RPAREN:737      case IES_LBRAC:738      case IES_RBRAC:739      case IES_INTEGER:740      case IES_REGISTER:741      case IES_INIT:742      case IES_OFFSET:743        State = IES_MINUS;744        // push minus operator if it is not a negate operator745        if (CurrState == IES_REGISTER || CurrState == IES_RPAREN ||746            CurrState == IES_INTEGER  || CurrState == IES_RBRAC  ||747            CurrState == IES_OFFSET)748          IC.pushOperator(IC_MINUS);749        else if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {750          // We have negate operator for Scale: it's illegal751          ErrMsg = "Scale can't be negative";752          return true;753        } else754          IC.pushOperator(IC_NEG);755        if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {756          // If we already have a BaseReg, then assume this is the IndexReg with757          // no explicit scale.758          if (!BaseReg) {759            BaseReg = TmpReg;760          } else {761            if (IndexReg)762              return regsUseUpError(ErrMsg);763            IndexReg = TmpReg;764            Scale = 0;765          }766        }767        break;768      }769      PrevState = CurrState;770      return false;771    }772    void onNot() {773      IntelExprState CurrState = State;774      switch (State) {775      default:776        State = IES_ERROR;777        break;778      case IES_OR:779      case IES_XOR:780      case IES_AND:781      case IES_EQ:782      case IES_NE:783      case IES_LT:784      case IES_LE:785      case IES_GT:786      case IES_GE:787      case IES_LSHIFT:788      case IES_RSHIFT:789      case IES_PLUS:790      case IES_MINUS:791      case IES_NOT:792      case IES_MULTIPLY:793      case IES_DIVIDE:794      case IES_MOD:795      case IES_LPAREN:796      case IES_LBRAC:797      case IES_INIT:798        State = IES_NOT;799        IC.pushOperator(IC_NOT);800        break;801      }802      PrevState = CurrState;803    }804    bool onRegister(MCRegister Reg, StringRef &ErrMsg) {805      IntelExprState CurrState = State;806      switch (State) {807      default:808        State = IES_ERROR;809        break;810      case IES_PLUS:811      case IES_LPAREN:812      case IES_LBRAC:813        State = IES_REGISTER;814        TmpReg = Reg;815        IC.pushOperand(IC_REGISTER);816        break;817      case IES_MULTIPLY:818        // Index Register - Scale * Register819        if (PrevState == IES_INTEGER) {820          if (IndexReg)821            return regsUseUpError(ErrMsg);822          State = IES_REGISTER;823          IndexReg = Reg;824          // Get the scale and replace the 'Scale * Register' with '0'.825          Scale = IC.popOperand();826          if (checkScale(Scale, ErrMsg))827            return true;828          IC.pushOperand(IC_IMM);829          IC.popOperator();830        } else {831          State = IES_ERROR;832        }833        break;834      }835      PrevState = CurrState;836      return false;837    }838    bool onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName,839                          const InlineAsmIdentifierInfo &IDInfo,840                          const AsmTypeInfo &Type, bool ParsingMSInlineAsm,841                          StringRef &ErrMsg) {842      // InlineAsm: Treat an enum value as an integer843      if (ParsingMSInlineAsm)844        if (IDInfo.isKind(InlineAsmIdentifierInfo::IK_EnumVal))845          return onInteger(IDInfo.Enum.EnumVal, ErrMsg);846      // Treat a symbolic constant like an integer847      if (auto *CE = dyn_cast<MCConstantExpr>(SymRef))848        return onInteger(CE->getValue(), ErrMsg);849      PrevState = State;850      switch (State) {851      default:852        State = IES_ERROR;853        break;854      case IES_CAST:855      case IES_PLUS:856      case IES_MINUS:857      case IES_NOT:858      case IES_INIT:859      case IES_LBRAC:860      case IES_LPAREN:861        if (setSymRef(SymRef, SymRefName, ErrMsg))862          return true;863        MemExpr = true;864        State = IES_INTEGER;865        IC.pushOperand(IC_IMM);866        if (ParsingMSInlineAsm)867          Info = IDInfo;868        setTypeInfo(Type);869        break;870      }871      return false;872    }873    bool onInteger(int64_t TmpInt, StringRef &ErrMsg) {874      IntelExprState CurrState = State;875      switch (State) {876      default:877        State = IES_ERROR;878        break;879      case IES_PLUS:880      case IES_MINUS:881      case IES_NOT:882      case IES_OR:883      case IES_XOR:884      case IES_AND:885      case IES_EQ:886      case IES_NE:887      case IES_LT:888      case IES_LE:889      case IES_GT:890      case IES_GE:891      case IES_LSHIFT:892      case IES_RSHIFT:893      case IES_DIVIDE:894      case IES_MOD:895      case IES_MULTIPLY:896      case IES_LPAREN:897      case IES_INIT:898      case IES_LBRAC:899        State = IES_INTEGER;900        if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {901          // Index Register - Register * Scale902          if (IndexReg)903            return regsUseUpError(ErrMsg);904          IndexReg = TmpReg;905          Scale = TmpInt;906          if (checkScale(Scale, ErrMsg))907            return true;908          // Get the scale and replace the 'Register * Scale' with '0'.909          IC.popOperator();910        } else {911          IC.pushOperand(IC_IMM, TmpInt);912        }913        break;914      }915      PrevState = CurrState;916      return false;917    }918    void onStar() {919      PrevState = State;920      switch (State) {921      default:922        State = IES_ERROR;923        break;924      case IES_INTEGER:925      case IES_REGISTER:926      case IES_RPAREN:927        State = IES_MULTIPLY;928        IC.pushOperator(IC_MULTIPLY);929        break;930      }931    }932    void onDivide() {933      PrevState = State;934      switch (State) {935      default:936        State = IES_ERROR;937        break;938      case IES_INTEGER:939      case IES_RPAREN:940        State = IES_DIVIDE;941        IC.pushOperator(IC_DIVIDE);942        break;943      }944    }945    void onMod() {946      PrevState = State;947      switch (State) {948      default:949        State = IES_ERROR;950        break;951      case IES_INTEGER:952      case IES_RPAREN:953        State = IES_MOD;954        IC.pushOperator(IC_MOD);955        break;956      }957    }958    bool onLBrac() {959      if (BracCount)960        return true;961      PrevState = State;962      switch (State) {963      default:964        State = IES_ERROR;965        break;966      case IES_RBRAC:967      case IES_INTEGER:968      case IES_RPAREN:969        State = IES_PLUS;970        IC.pushOperator(IC_PLUS);971        CurType.Length = 1;972        CurType.Size = CurType.ElementSize;973        break;974      case IES_INIT:975      case IES_CAST:976        assert(!BracCount && "BracCount should be zero on parsing's start");977        State = IES_LBRAC;978        break;979      }980      MemExpr = true;981      BracketUsed = true;982      BracCount++;983      return false;984    }985    bool onRBrac(StringRef &ErrMsg) {986      IntelExprState CurrState = State;987      switch (State) {988      default:989        State = IES_ERROR;990        break;991      case IES_INTEGER:992      case IES_OFFSET:993      case IES_REGISTER:994      case IES_RPAREN:995        if (BracCount-- != 1) {996          ErrMsg = "unexpected bracket encountered";997          return true;998        }999        State = IES_RBRAC;1000        if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {1001          // If we already have a BaseReg, then assume this is the IndexReg with1002          // no explicit scale.1003          if (!BaseReg) {1004            BaseReg = TmpReg;1005          } else {1006            if (IndexReg)1007              return regsUseUpError(ErrMsg);1008            IndexReg = TmpReg;1009            Scale = 0;1010          }1011        }1012        break;1013      }1014      PrevState = CurrState;1015      return false;1016    }1017    void onLParen() {1018      IntelExprState CurrState = State;1019      switch (State) {1020      default:1021        State = IES_ERROR;1022        break;1023      case IES_PLUS:1024      case IES_MINUS:1025      case IES_NOT:1026      case IES_OR:1027      case IES_XOR:1028      case IES_AND:1029      case IES_EQ:1030      case IES_NE:1031      case IES_LT:1032      case IES_LE:1033      case IES_GT:1034      case IES_GE:1035      case IES_LSHIFT:1036      case IES_RSHIFT:1037      case IES_MULTIPLY:1038      case IES_DIVIDE:1039      case IES_MOD:1040      case IES_LPAREN:1041      case IES_INIT:1042      case IES_LBRAC:1043        State = IES_LPAREN;1044        IC.pushOperator(IC_LPAREN);1045        break;1046      }1047      PrevState = CurrState;1048    }1049    bool onRParen(StringRef &ErrMsg) {1050      IntelExprState CurrState = State;1051      switch (State) {1052      default:1053        State = IES_ERROR;1054        break;1055      case IES_INTEGER:1056      case IES_OFFSET:1057      case IES_REGISTER:1058      case IES_RBRAC:1059      case IES_RPAREN:1060        State = IES_RPAREN;1061        // In the case of a multiply, onRegister has already set IndexReg1062        // directly, with appropriate scale.1063        // Otherwise if we just saw a register it has only been stored in1064        // TmpReg, so we need to store it into the state machine.1065        if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {1066          // If we already have a BaseReg, then assume this is the IndexReg with1067          // no explicit scale.1068          if (!BaseReg) {1069            BaseReg = TmpReg;1070          } else {1071            if (IndexReg)1072              return regsUseUpError(ErrMsg);1073            IndexReg = TmpReg;1074            Scale = 0;1075          }1076        }1077        IC.pushOperator(IC_RPAREN);1078        break;1079      }1080      PrevState = CurrState;1081      return false;1082    }1083    bool onOffset(const MCExpr *Val, SMLoc OffsetLoc, StringRef ID,1084                  const InlineAsmIdentifierInfo &IDInfo,1085                  bool ParsingMSInlineAsm, StringRef &ErrMsg) {1086      PrevState = State;1087      switch (State) {1088      default:1089        ErrMsg = "unexpected offset operator expression";1090        return true;1091      case IES_PLUS:1092      case IES_INIT:1093      case IES_LBRAC:1094        if (setSymRef(Val, ID, ErrMsg))1095          return true;1096        OffsetOperator = true;1097        OffsetOperatorLoc = OffsetLoc;1098        State = IES_OFFSET;1099        // As we cannot yet resolve the actual value (offset), we retain1100        // the requested semantics by pushing a '0' to the operands stack1101        IC.pushOperand(IC_IMM);1102        if (ParsingMSInlineAsm) {1103          Info = IDInfo;1104        }1105        break;1106      }1107      return false;1108    }1109    void onCast(AsmTypeInfo Info) {1110      PrevState = State;1111      switch (State) {1112      default:1113        State = IES_ERROR;1114        break;1115      case IES_LPAREN:1116        setTypeInfo(Info);1117        State = IES_CAST;1118        break;1119      }1120    }1121    void setTypeInfo(AsmTypeInfo Type) { CurType = Type; }1122  };1123 1124  bool Error(SMLoc L, const Twine &Msg, SMRange Range = {},1125             bool MatchingInlineAsm = false) {1126    MCAsmParser &Parser = getParser();1127    if (MatchingInlineAsm) {1128      return false;1129    }1130    return Parser.Error(L, Msg, Range);1131  }1132 1133  bool MatchRegisterByName(MCRegister &RegNo, StringRef RegName, SMLoc StartLoc,1134                           SMLoc EndLoc);1135  bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,1136                     bool RestoreOnFailure);1137 1138  std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc);1139  std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc);1140  bool IsSIReg(MCRegister Reg);1141  MCRegister GetSIDIForRegClass(unsigned RegClassID, bool IsSIReg);1142  void1143  AddDefaultSrcDestOperands(OperandVector &Operands,1144                            std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,1145                            std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);1146  bool VerifyAndAdjustOperands(OperandVector &OrigOperands,1147                               OperandVector &FinalOperands);1148  bool parseOperand(OperandVector &Operands, StringRef Name);1149  bool parseATTOperand(OperandVector &Operands);1150  bool parseIntelOperand(OperandVector &Operands, StringRef Name);1151  bool ParseIntelOffsetOperator(const MCExpr *&Val, StringRef &ID,1152                                InlineAsmIdentifierInfo &Info, SMLoc &End);1153  bool ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End);1154  unsigned IdentifyIntelInlineAsmOperator(StringRef Name);1155  unsigned ParseIntelInlineAsmOperator(unsigned OpKind);1156  unsigned IdentifyMasmOperator(StringRef Name);1157  bool ParseMasmOperator(unsigned OpKind, int64_t &Val);1158  bool ParseRoundingModeOp(SMLoc Start, OperandVector &Operands);1159  bool parseCFlagsOp(OperandVector &Operands);1160  bool ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM,1161                               bool &ParseError, SMLoc &End);1162  bool ParseMasmNamedOperator(StringRef Name, IntelExprStateMachine &SM,1163                              bool &ParseError, SMLoc &End);1164  void RewriteIntelExpression(IntelExprStateMachine &SM, SMLoc Start,1165                              SMLoc End);1166  bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);1167  bool ParseIntelInlineAsmIdentifier(const MCExpr *&Val, StringRef &Identifier,1168                                     InlineAsmIdentifierInfo &Info,1169                                     bool IsUnevaluatedOperand, SMLoc &End,1170                                     bool IsParsingOffsetOperator = false);1171  void tryParseOperandIdx(AsmToken::TokenKind PrevTK,1172                          IntelExprStateMachine &SM);1173 1174  bool ParseMemOperand(MCRegister SegReg, const MCExpr *Disp, SMLoc StartLoc,1175                       SMLoc EndLoc, OperandVector &Operands);1176 1177  X86::CondCode ParseConditionCode(StringRef CCode);1178 1179  bool ParseIntelMemoryOperandSize(unsigned &Size, StringRef *SizeStr);1180  bool CreateMemForMSInlineAsm(MCRegister SegReg, const MCExpr *Disp,1181                               MCRegister BaseReg, MCRegister IndexReg,1182                               unsigned Scale, bool NonAbsMem, SMLoc Start,1183                               SMLoc End, unsigned Size, StringRef Identifier,1184                               const InlineAsmIdentifierInfo &Info,1185                               OperandVector &Operands);1186 1187  bool parseDirectiveArch();1188  bool parseDirectiveNops(SMLoc L);1189  bool parseDirectiveEven(SMLoc L);1190  bool ParseDirectiveCode(StringRef IDVal, SMLoc L);1191 1192  /// CodeView FPO data directives.1193  bool parseDirectiveFPOProc(SMLoc L);1194  bool parseDirectiveFPOSetFrame(SMLoc L);1195  bool parseDirectiveFPOPushReg(SMLoc L);1196  bool parseDirectiveFPOStackAlloc(SMLoc L);1197  bool parseDirectiveFPOStackAlign(SMLoc L);1198  bool parseDirectiveFPOEndPrologue(SMLoc L);1199  bool parseDirectiveFPOEndProc(SMLoc L);1200 1201  /// SEH directives.1202  bool parseSEHRegisterNumber(unsigned RegClassID, MCRegister &RegNo);1203  bool parseDirectiveSEHPushReg(SMLoc);1204  bool parseDirectiveSEHSetFrame(SMLoc);1205  bool parseDirectiveSEHSaveReg(SMLoc);1206  bool parseDirectiveSEHSaveXMM(SMLoc);1207  bool parseDirectiveSEHPushFrame(SMLoc);1208 1209  unsigned checkTargetMatchPredicate(MCInst &Inst) override;1210 1211  bool validateInstruction(MCInst &Inst, const OperandVector &Ops);1212  bool processInstruction(MCInst &Inst, const OperandVector &Ops);1213 1214  // Load Value Injection (LVI) Mitigations for machine code1215  void emitWarningForSpecialLVIInstruction(SMLoc Loc);1216  void applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out);1217  void applyLVILoadHardeningMitigation(MCInst &Inst, MCStreamer &Out);1218 1219  /// Wrapper around MCStreamer::emitInstruction(). Possibly adds1220  /// instrumentation around Inst.1221  void emitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out);1222 1223  bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,1224                               OperandVector &Operands, MCStreamer &Out,1225                               uint64_t &ErrorInfo,1226                               bool MatchingInlineAsm) override;1227 1228  void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, OperandVector &Operands,1229                         MCStreamer &Out, bool MatchingInlineAsm);1230 1231  bool ErrorMissingFeature(SMLoc IDLoc, const FeatureBitset &MissingFeatures,1232                           bool MatchingInlineAsm);1233 1234  bool matchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode, MCInst &Inst,1235                                  OperandVector &Operands, MCStreamer &Out,1236                                  uint64_t &ErrorInfo, bool MatchingInlineAsm);1237 1238  bool matchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode, MCInst &Inst,1239                                    OperandVector &Operands, MCStreamer &Out,1240                                    uint64_t &ErrorInfo,1241                                    bool MatchingInlineAsm);1242 1243  bool omitRegisterFromClobberLists(MCRegister Reg) override;1244 1245  /// Parses AVX512 specific operand primitives: masked registers ({%k<NUM>}, {z})1246  /// and memory broadcasting ({1to<NUM>}) primitives, updating Operands vector if required.1247  /// return false if no parsing errors occurred, true otherwise.1248  bool HandleAVX512Operand(OperandVector &Operands);1249 1250  bool ParseZ(std::unique_ptr<X86Operand> &Z, SMLoc StartLoc);1251 1252  bool is64BitMode() const {1253    // FIXME: Can tablegen auto-generate this?1254    return getSTI().hasFeature(X86::Is64Bit);1255  }1256  bool is32BitMode() const {1257    // FIXME: Can tablegen auto-generate this?1258    return getSTI().hasFeature(X86::Is32Bit);1259  }1260  bool is16BitMode() const {1261    // FIXME: Can tablegen auto-generate this?1262    return getSTI().hasFeature(X86::Is16Bit);1263  }1264  void SwitchMode(unsigned mode) {1265    MCSubtargetInfo &STI = copySTI();1266    FeatureBitset AllModes({X86::Is64Bit, X86::Is32Bit, X86::Is16Bit});1267    FeatureBitset OldMode = STI.getFeatureBits() & AllModes;1268    FeatureBitset FB = ComputeAvailableFeatures(1269      STI.ToggleFeature(OldMode.flip(mode)));1270    setAvailableFeatures(FB);1271 1272    assert(FeatureBitset({mode}) == (STI.getFeatureBits() & AllModes));1273  }1274 1275  unsigned getPointerWidth() {1276    if (is16BitMode()) return 16;1277    if (is32BitMode()) return 32;1278    if (is64BitMode()) return 64;1279    llvm_unreachable("invalid mode");1280  }1281 1282  bool isParsingIntelSyntax() {1283    return getParser().getAssemblerDialect();1284  }1285 1286  /// @name Auto-generated Matcher Functions1287  /// {1288 1289#define GET_ASSEMBLER_HEADER1290#include "X86GenAsmMatcher.inc"1291 1292  /// }1293 1294public:1295  enum X86MatchResultTy {1296    Match_Unsupported = FIRST_TARGET_MATCH_RESULT_TY,1297#define GET_OPERAND_DIAGNOSTIC_TYPES1298#include "X86GenAsmMatcher.inc"1299  };1300 1301  X86AsmParser(const MCSubtargetInfo &sti, MCAsmParser &Parser,1302               const MCInstrInfo &mii, const MCTargetOptions &Options)1303      : MCTargetAsmParser(Options, sti, mii),  InstInfo(nullptr),1304        Code16GCC(false) {1305 1306    Parser.addAliasForDirective(".word", ".2byte");1307 1308    // Initialize the set of available features.1309    setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));1310  }1311 1312  bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;1313  ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,1314                               SMLoc &EndLoc) override;1315 1316  bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) override;1317 1318  bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,1319                        SMLoc NameLoc, OperandVector &Operands) override;1320 1321  bool ParseDirective(AsmToken DirectiveID) override;1322};1323} // end anonymous namespace1324 1325#define GET_REGISTER_MATCHER1326#define GET_SUBTARGET_FEATURE_NAME1327#include "X86GenAsmMatcher.inc"1328 1329static bool CheckBaseRegAndIndexRegAndScale(MCRegister BaseReg,1330                                            MCRegister IndexReg, unsigned Scale,1331                                            bool Is64BitMode,1332                                            StringRef &ErrMsg) {1333  // If we have both a base register and an index register make sure they are1334  // both 64-bit or 32-bit registers.1335  // To support VSIB, IndexReg can be 128-bit or 256-bit registers.1336 1337  if (BaseReg &&1338      !(BaseReg == X86::RIP || BaseReg == X86::EIP ||1339        X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) ||1340        X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) ||1341        X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg))) {1342    ErrMsg = "invalid base+index expression";1343    return true;1344  }1345 1346  if (IndexReg &&1347      !(IndexReg == X86::EIZ || IndexReg == X86::RIZ ||1348        X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||1349        X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||1350        X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg) ||1351        X86MCRegisterClasses[X86::VR128XRegClassID].contains(IndexReg) ||1352        X86MCRegisterClasses[X86::VR256XRegClassID].contains(IndexReg) ||1353        X86MCRegisterClasses[X86::VR512RegClassID].contains(IndexReg))) {1354    ErrMsg = "invalid base+index expression";1355    return true;1356  }1357 1358  if (((BaseReg == X86::RIP || BaseReg == X86::EIP) && IndexReg) ||1359      IndexReg == X86::EIP || IndexReg == X86::RIP || IndexReg == X86::ESP ||1360      IndexReg == X86::RSP) {1361    ErrMsg = "invalid base+index expression";1362    return true;1363  }1364 1365  // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed,1366  // and then only in non-64-bit modes.1367  if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&1368      (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP &&1369                       BaseReg != X86::SI && BaseReg != X86::DI))) {1370    ErrMsg = "invalid 16-bit base register";1371    return true;1372  }1373 1374  if (!BaseReg &&1375      X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {1376    ErrMsg = "16-bit memory operand may not include only index register";1377    return true;1378  }1379 1380  if (BaseReg && IndexReg) {1381    if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&1382        (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||1383         X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||1384         IndexReg == X86::EIZ)) {1385      ErrMsg = "base register is 64-bit, but index register is not";1386      return true;1387    }1388    if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) &&1389        (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||1390         X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg) ||1391         IndexReg == X86::RIZ)) {1392      ErrMsg = "base register is 32-bit, but index register is not";1393      return true;1394    }1395    if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) {1396      if (X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||1397          X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) {1398        ErrMsg = "base register is 16-bit, but index register is not";1399        return true;1400      }1401      if ((BaseReg != X86::BX && BaseReg != X86::BP) ||1402          (IndexReg != X86::SI && IndexReg != X86::DI)) {1403        ErrMsg = "invalid 16-bit base/index register combination";1404        return true;1405      }1406    }1407  }1408 1409  // RIP/EIP-relative addressing is only supported in 64-bit mode.1410  if (!Is64BitMode && (BaseReg == X86::RIP || BaseReg == X86::EIP)) {1411    ErrMsg = "IP-relative addressing requires 64-bit mode";1412    return true;1413  }1414 1415  return checkScale(Scale, ErrMsg);1416}1417 1418bool X86AsmParser::MatchRegisterByName(MCRegister &RegNo, StringRef RegName,1419                                       SMLoc StartLoc, SMLoc EndLoc) {1420  // If we encounter a %, ignore it. This code handles registers with and1421  // without the prefix, unprefixed registers can occur in cfi directives.1422  RegName.consume_front("%");1423 1424  RegNo = MatchRegisterName(RegName);1425 1426  // If the match failed, try the register name as lowercase.1427  if (!RegNo)1428    RegNo = MatchRegisterName(RegName.lower());1429 1430  // The "flags" and "mxcsr" registers cannot be referenced directly.1431  // Treat it as an identifier instead.1432  if (isParsingMSInlineAsm() && isParsingIntelSyntax() &&1433      (RegNo == X86::EFLAGS || RegNo == X86::MXCSR))1434    RegNo = MCRegister();1435 1436  if (!is64BitMode()) {1437    // FIXME: This should be done using Requires<Not64BitMode> and1438    // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also1439    // checked.1440    if (RegNo == X86::RIZ || RegNo == X86::RIP ||1441        X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||1442        X86II::isX86_64NonExtLowByteReg(RegNo) ||1443        X86II::isX86_64ExtendedReg(RegNo)) {1444      return Error(StartLoc,1445                   "register %" + RegName + " is only available in 64-bit mode",1446                   SMRange(StartLoc, EndLoc));1447    }1448  }1449 1450  if (X86II::isApxExtendedReg(RegNo))1451    UseApxExtendedReg = true;1452 1453  // If this is "db[0-15]", match it as an alias1454  // for dr[0-15].1455  if (!RegNo && RegName.starts_with("db")) {1456    if (RegName.size() == 3) {1457      switch (RegName[2]) {1458      case '0':1459        RegNo = X86::DR0;1460        break;1461      case '1':1462        RegNo = X86::DR1;1463        break;1464      case '2':1465        RegNo = X86::DR2;1466        break;1467      case '3':1468        RegNo = X86::DR3;1469        break;1470      case '4':1471        RegNo = X86::DR4;1472        break;1473      case '5':1474        RegNo = X86::DR5;1475        break;1476      case '6':1477        RegNo = X86::DR6;1478        break;1479      case '7':1480        RegNo = X86::DR7;1481        break;1482      case '8':1483        RegNo = X86::DR8;1484        break;1485      case '9':1486        RegNo = X86::DR9;1487        break;1488      }1489    } else if (RegName.size() == 4 && RegName[2] == '1') {1490      switch (RegName[3]) {1491      case '0':1492        RegNo = X86::DR10;1493        break;1494      case '1':1495        RegNo = X86::DR11;1496        break;1497      case '2':1498        RegNo = X86::DR12;1499        break;1500      case '3':1501        RegNo = X86::DR13;1502        break;1503      case '4':1504        RegNo = X86::DR14;1505        break;1506      case '5':1507        RegNo = X86::DR15;1508        break;1509      }1510    }1511  }1512 1513  if (!RegNo) {1514    if (isParsingIntelSyntax())1515      return true;1516    return Error(StartLoc, "invalid register name", SMRange(StartLoc, EndLoc));1517  }1518  return false;1519}1520 1521bool X86AsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,1522                                 SMLoc &EndLoc, bool RestoreOnFailure) {1523  MCAsmParser &Parser = getParser();1524  AsmLexer &Lexer = getLexer();1525  RegNo = MCRegister();1526 1527  SmallVector<AsmToken, 5> Tokens;1528  auto OnFailure = [RestoreOnFailure, &Lexer, &Tokens]() {1529    if (RestoreOnFailure) {1530      while (!Tokens.empty()) {1531        Lexer.UnLex(Tokens.pop_back_val());1532      }1533    }1534  };1535 1536  const AsmToken &PercentTok = Parser.getTok();1537  StartLoc = PercentTok.getLoc();1538 1539  // If we encounter a %, ignore it. This code handles registers with and1540  // without the prefix, unprefixed registers can occur in cfi directives.1541  if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent)) {1542    Tokens.push_back(PercentTok);1543    Parser.Lex(); // Eat percent token.1544  }1545 1546  const AsmToken &Tok = Parser.getTok();1547  EndLoc = Tok.getEndLoc();1548 1549  if (Tok.isNot(AsmToken::Identifier)) {1550    OnFailure();1551    if (isParsingIntelSyntax()) return true;1552    return Error(StartLoc, "invalid register name",1553                 SMRange(StartLoc, EndLoc));1554  }1555 1556  if (MatchRegisterByName(RegNo, Tok.getString(), StartLoc, EndLoc)) {1557    OnFailure();1558    return true;1559  }1560 1561  // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.1562  if (RegNo == X86::ST0) {1563    Tokens.push_back(Tok);1564    Parser.Lex(); // Eat 'st'1565 1566    // Check to see if we have '(4)' after %st.1567    if (Lexer.isNot(AsmToken::LParen))1568      return false;1569    // Lex the paren.1570    Tokens.push_back(Parser.getTok());1571    Parser.Lex();1572 1573    const AsmToken &IntTok = Parser.getTok();1574    if (IntTok.isNot(AsmToken::Integer)) {1575      OnFailure();1576      return Error(IntTok.getLoc(), "expected stack index");1577    }1578    switch (IntTok.getIntVal()) {1579    case 0: RegNo = X86::ST0; break;1580    case 1: RegNo = X86::ST1; break;1581    case 2: RegNo = X86::ST2; break;1582    case 3: RegNo = X86::ST3; break;1583    case 4: RegNo = X86::ST4; break;1584    case 5: RegNo = X86::ST5; break;1585    case 6: RegNo = X86::ST6; break;1586    case 7: RegNo = X86::ST7; break;1587    default:1588      OnFailure();1589      return Error(IntTok.getLoc(), "invalid stack index");1590    }1591 1592    // Lex IntTok1593    Tokens.push_back(IntTok);1594    Parser.Lex();1595    if (Lexer.isNot(AsmToken::RParen)) {1596      OnFailure();1597      return Error(Parser.getTok().getLoc(), "expected ')'");1598    }1599 1600    EndLoc = Parser.getTok().getEndLoc();1601    Parser.Lex(); // Eat ')'1602    return false;1603  }1604 1605  EndLoc = Parser.getTok().getEndLoc();1606 1607  if (!RegNo) {1608    OnFailure();1609    if (isParsingIntelSyntax()) return true;1610    return Error(StartLoc, "invalid register name",1611                 SMRange(StartLoc, EndLoc));1612  }1613 1614  Parser.Lex(); // Eat identifier token.1615  return false;1616}1617 1618bool X86AsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,1619                                 SMLoc &EndLoc) {1620  return ParseRegister(Reg, StartLoc, EndLoc, /*RestoreOnFailure=*/false);1621}1622 1623ParseStatus X86AsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,1624                                           SMLoc &EndLoc) {1625  bool Result = ParseRegister(Reg, StartLoc, EndLoc, /*RestoreOnFailure=*/true);1626  bool PendingErrors = getParser().hasPendingError();1627  getParser().clearPendingErrors();1628  if (PendingErrors)1629    return ParseStatus::Failure;1630  if (Result)1631    return ParseStatus::NoMatch;1632  return ParseStatus::Success;1633}1634 1635std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {1636  bool Parse32 = is32BitMode() || Code16GCC;1637  MCRegister Basereg =1638      is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);1639  const MCExpr *Disp = MCConstantExpr::create(0, getContext());1640  return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,1641                               /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1,1642                               Loc, Loc, 0);1643}1644 1645std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {1646  bool Parse32 = is32BitMode() || Code16GCC;1647  MCRegister Basereg =1648      is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);1649  const MCExpr *Disp = MCConstantExpr::create(0, getContext());1650  return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,1651                               /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1,1652                               Loc, Loc, 0);1653}1654 1655bool X86AsmParser::IsSIReg(MCRegister Reg) {1656  switch (Reg.id()) {1657  default: llvm_unreachable("Only (R|E)SI and (R|E)DI are expected!");1658  case X86::RSI:1659  case X86::ESI:1660  case X86::SI:1661    return true;1662  case X86::RDI:1663  case X86::EDI:1664  case X86::DI:1665    return false;1666  }1667}1668 1669MCRegister X86AsmParser::GetSIDIForRegClass(unsigned RegClassID, bool IsSIReg) {1670  switch (RegClassID) {1671  default: llvm_unreachable("Unexpected register class");1672  case X86::GR64RegClassID:1673    return IsSIReg ? X86::RSI : X86::RDI;1674  case X86::GR32RegClassID:1675    return IsSIReg ? X86::ESI : X86::EDI;1676  case X86::GR16RegClassID:1677    return IsSIReg ? X86::SI : X86::DI;1678  }1679}1680 1681void X86AsmParser::AddDefaultSrcDestOperands(1682    OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,1683    std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {1684  if (isParsingIntelSyntax()) {1685    Operands.push_back(std::move(Dst));1686    Operands.push_back(std::move(Src));1687  }1688  else {1689    Operands.push_back(std::move(Src));1690    Operands.push_back(std::move(Dst));1691  }1692}1693 1694bool X86AsmParser::VerifyAndAdjustOperands(OperandVector &OrigOperands,1695                                           OperandVector &FinalOperands) {1696 1697  if (OrigOperands.size() > 1) {1698    // Check if sizes match, OrigOperands also contains the instruction name1699    assert(OrigOperands.size() == FinalOperands.size() + 1 &&1700           "Operand size mismatch");1701 1702    SmallVector<std::pair<SMLoc, std::string>, 2> Warnings;1703    // Verify types match1704    int RegClassID = -1;1705    for (unsigned int i = 0; i < FinalOperands.size(); ++i) {1706      X86Operand &OrigOp = static_cast<X86Operand &>(*OrigOperands[i + 1]);1707      X86Operand &FinalOp = static_cast<X86Operand &>(*FinalOperands[i]);1708 1709      if (FinalOp.isReg() &&1710          (!OrigOp.isReg() || FinalOp.getReg() != OrigOp.getReg()))1711        // Return false and let a normal complaint about bogus operands happen1712        return false;1713 1714      if (FinalOp.isMem()) {1715 1716        if (!OrigOp.isMem())1717          // Return false and let a normal complaint about bogus operands happen1718          return false;1719 1720        MCRegister OrigReg = OrigOp.Mem.BaseReg;1721        MCRegister FinalReg = FinalOp.Mem.BaseReg;1722 1723        // If we've already encounterd a register class, make sure all register1724        // bases are of the same register class1725        if (RegClassID != -1 &&1726            !X86MCRegisterClasses[RegClassID].contains(OrigReg)) {1727          return Error(OrigOp.getStartLoc(),1728                       "mismatching source and destination index registers");1729        }1730 1731        if (X86MCRegisterClasses[X86::GR64RegClassID].contains(OrigReg))1732          RegClassID = X86::GR64RegClassID;1733        else if (X86MCRegisterClasses[X86::GR32RegClassID].contains(OrigReg))1734          RegClassID = X86::GR32RegClassID;1735        else if (X86MCRegisterClasses[X86::GR16RegClassID].contains(OrigReg))1736          RegClassID = X86::GR16RegClassID;1737        else1738          // Unexpected register class type1739          // Return false and let a normal complaint about bogus operands happen1740          return false;1741 1742        bool IsSI = IsSIReg(FinalReg);1743        FinalReg = GetSIDIForRegClass(RegClassID, IsSI);1744 1745        if (FinalReg != OrigReg) {1746          std::string RegName = IsSI ? "ES:(R|E)SI" : "ES:(R|E)DI";1747          Warnings.push_back(std::make_pair(1748              OrigOp.getStartLoc(),1749              "memory operand is only for determining the size, " + RegName +1750                  " will be used for the location"));1751        }1752 1753        FinalOp.Mem.Size = OrigOp.Mem.Size;1754        FinalOp.Mem.SegReg = OrigOp.Mem.SegReg;1755        FinalOp.Mem.BaseReg = FinalReg;1756      }1757    }1758 1759    // Produce warnings only if all the operands passed the adjustment - prevent1760    // legal cases like "movsd (%rax), %xmm0" mistakenly produce warnings1761    for (auto &WarningMsg : Warnings) {1762      Warning(WarningMsg.first, WarningMsg.second);1763    }1764 1765    // Remove old operands1766    for (unsigned int i = 0; i < FinalOperands.size(); ++i)1767      OrigOperands.pop_back();1768  }1769  // OrigOperands.append(FinalOperands.begin(), FinalOperands.end());1770  for (auto &Op : FinalOperands)1771    OrigOperands.push_back(std::move(Op));1772 1773  return false;1774}1775 1776bool X86AsmParser::parseOperand(OperandVector &Operands, StringRef Name) {1777  if (isParsingIntelSyntax())1778    return parseIntelOperand(Operands, Name);1779 1780  return parseATTOperand(Operands);1781}1782 1783bool X86AsmParser::CreateMemForMSInlineAsm(1784    MCRegister SegReg, const MCExpr *Disp, MCRegister BaseReg,1785    MCRegister IndexReg, unsigned Scale, bool NonAbsMem, SMLoc Start, SMLoc End,1786    unsigned Size, StringRef Identifier, const InlineAsmIdentifierInfo &Info,1787    OperandVector &Operands) {1788  // If we found a decl other than a VarDecl, then assume it is a FuncDecl or1789  // some other label reference.1790  if (Info.isKind(InlineAsmIdentifierInfo::IK_Label)) {1791    // Create an absolute memory reference in order to match against1792    // instructions taking a PC relative operand.1793    Operands.push_back(X86Operand::CreateMem(getPointerWidth(), Disp, Start,1794                                             End, Size, Identifier,1795                                             Info.Label.Decl));1796    return false;1797  }1798  // We either have a direct symbol reference, or an offset from a symbol.  The1799  // parser always puts the symbol on the LHS, so look there for size1800  // calculation purposes.1801  unsigned FrontendSize = 0;1802  void *Decl = nullptr;1803  bool IsGlobalLV = false;1804  if (Info.isKind(InlineAsmIdentifierInfo::IK_Var)) {1805    // Size is in terms of bits in this context.1806    FrontendSize = Info.Var.Type * 8;1807    Decl = Info.Var.Decl;1808    IsGlobalLV = Info.Var.IsGlobalLV;1809  }1810  // It is widely common for MS InlineAsm to use a global variable and one/two1811  // registers in a mmory expression, and though unaccessible via rip/eip.1812  if (IsGlobalLV) {1813    if (BaseReg || IndexReg) {1814      Operands.push_back(X86Operand::CreateMem(getPointerWidth(), Disp, Start,1815                                               End, Size, Identifier, Decl, 0,1816                                               BaseReg && IndexReg));1817      return false;1818    }1819    if (NonAbsMem)1820      BaseReg = 1; // Make isAbsMem() false1821  }1822  Operands.push_back(X86Operand::CreateMem(1823      getPointerWidth(), SegReg, Disp, BaseReg, IndexReg, Scale, Start, End,1824      Size,1825      /*DefaultBaseReg=*/X86::RIP, Identifier, Decl, FrontendSize));1826  return false;1827}1828 1829// Some binary bitwise operators have a named synonymous1830// Query a candidate string for being such a named operator1831// and if so - invoke the appropriate handler1832bool X86AsmParser::ParseIntelNamedOperator(StringRef Name,1833                                           IntelExprStateMachine &SM,1834                                           bool &ParseError, SMLoc &End) {1835  // A named operator should be either lower or upper case, but not a mix...1836  // except in MASM, which uses full case-insensitivity.1837  if (Name != Name.lower() && Name != Name.upper() &&1838      !getParser().isParsingMasm())1839    return false;1840  if (Name.equals_insensitive("not")) {1841    SM.onNot();1842  } else if (Name.equals_insensitive("or")) {1843    SM.onOr();1844  } else if (Name.equals_insensitive("shl")) {1845    SM.onLShift();1846  } else if (Name.equals_insensitive("shr")) {1847    SM.onRShift();1848  } else if (Name.equals_insensitive("xor")) {1849    SM.onXor();1850  } else if (Name.equals_insensitive("and")) {1851    SM.onAnd();1852  } else if (Name.equals_insensitive("mod")) {1853    SM.onMod();1854  } else if (Name.equals_insensitive("offset")) {1855    SMLoc OffsetLoc = getTok().getLoc();1856    const MCExpr *Val = nullptr;1857    StringRef ID;1858    InlineAsmIdentifierInfo Info;1859    ParseError = ParseIntelOffsetOperator(Val, ID, Info, End);1860    if (ParseError)1861      return true;1862    StringRef ErrMsg;1863    ParseError =1864        SM.onOffset(Val, OffsetLoc, ID, Info, isParsingMSInlineAsm(), ErrMsg);1865    if (ParseError)1866      return Error(SMLoc::getFromPointer(Name.data()), ErrMsg);1867  } else {1868    return false;1869  }1870  if (!Name.equals_insensitive("offset"))1871    End = consumeToken();1872  return true;1873}1874bool X86AsmParser::ParseMasmNamedOperator(StringRef Name,1875                                          IntelExprStateMachine &SM,1876                                          bool &ParseError, SMLoc &End) {1877  if (Name.equals_insensitive("eq")) {1878    SM.onEq();1879  } else if (Name.equals_insensitive("ne")) {1880    SM.onNE();1881  } else if (Name.equals_insensitive("lt")) {1882    SM.onLT();1883  } else if (Name.equals_insensitive("le")) {1884    SM.onLE();1885  } else if (Name.equals_insensitive("gt")) {1886    SM.onGT();1887  } else if (Name.equals_insensitive("ge")) {1888    SM.onGE();1889  } else {1890    return false;1891  }1892  End = consumeToken();1893  return true;1894}1895 1896// Check if current intel expression append after an operand.1897// Like: [Operand][Intel Expression]1898void X86AsmParser::tryParseOperandIdx(AsmToken::TokenKind PrevTK,1899                                      IntelExprStateMachine &SM) {1900  if (PrevTK != AsmToken::RBrac)1901    return;1902 1903  SM.setAppendAfterOperand();1904}1905 1906bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {1907  MCAsmParser &Parser = getParser();1908  StringRef ErrMsg;1909 1910  AsmToken::TokenKind PrevTK = AsmToken::Error;1911 1912  if (getContext().getObjectFileInfo()->isPositionIndependent())1913    SM.setPIC();1914 1915  bool Done = false;1916  while (!Done) {1917    // Get a fresh reference on each loop iteration in case the previous1918    // iteration moved the token storage during UnLex().1919    const AsmToken &Tok = Parser.getTok();1920 1921    bool UpdateLocLex = true;1922    AsmToken::TokenKind TK = getLexer().getKind();1923 1924    switch (TK) {1925    default:1926      if ((Done = SM.isValidEndState()))1927        break;1928      return Error(Tok.getLoc(), "unknown token in expression");1929    case AsmToken::Error:1930      return Error(getLexer().getErrLoc(), getLexer().getErr());1931      break;1932    case AsmToken::Real:1933      // DotOperator: [ebx].01934      UpdateLocLex = false;1935      if (ParseIntelDotOperator(SM, End))1936        return true;1937      break;1938    case AsmToken::Dot:1939      if (!Parser.isParsingMasm()) {1940        if ((Done = SM.isValidEndState()))1941          break;1942        return Error(Tok.getLoc(), "unknown token in expression");1943      }1944      // MASM allows spaces around the dot operator (e.g., "var . x")1945      Lex();1946      UpdateLocLex = false;1947      if (ParseIntelDotOperator(SM, End))1948        return true;1949      break;1950    case AsmToken::Dollar:1951      if (!Parser.isParsingMasm()) {1952        if ((Done = SM.isValidEndState()))1953          break;1954        return Error(Tok.getLoc(), "unknown token in expression");1955      }1956      [[fallthrough]];1957    case AsmToken::String: {1958      if (Parser.isParsingMasm()) {1959        // MASM parsers handle strings in expressions as constants.1960        SMLoc ValueLoc = Tok.getLoc();1961        int64_t Res;1962        const MCExpr *Val;1963        if (Parser.parsePrimaryExpr(Val, End, nullptr))1964          return true;1965        UpdateLocLex = false;1966        if (!Val->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))1967          return Error(ValueLoc, "expected absolute value");1968        if (SM.onInteger(Res, ErrMsg))1969          return Error(ValueLoc, ErrMsg);1970        break;1971      }1972      [[fallthrough]];1973    }1974    case AsmToken::At:1975    case AsmToken::Identifier: {1976      SMLoc IdentLoc = Tok.getLoc();1977      StringRef Identifier = Tok.getString();1978      UpdateLocLex = false;1979      if (Parser.isParsingMasm()) {1980        size_t DotOffset = Identifier.find_first_of('.');1981        if (DotOffset != StringRef::npos) {1982          consumeToken();1983          StringRef LHS = Identifier.slice(0, DotOffset);1984          StringRef Dot = Identifier.substr(DotOffset, 1);1985          StringRef RHS = Identifier.substr(DotOffset + 1);1986          if (!RHS.empty()) {1987            getLexer().UnLex(AsmToken(AsmToken::Identifier, RHS));1988          }1989          getLexer().UnLex(AsmToken(AsmToken::Dot, Dot));1990          if (!LHS.empty()) {1991            getLexer().UnLex(AsmToken(AsmToken::Identifier, LHS));1992          }1993          break;1994        }1995      }1996      // (MASM only) <TYPE> PTR operator1997      if (Parser.isParsingMasm()) {1998        const AsmToken &NextTok = getLexer().peekTok();1999        if (NextTok.is(AsmToken::Identifier) &&2000            NextTok.getIdentifier().equals_insensitive("ptr")) {2001          AsmTypeInfo Info;2002          if (Parser.lookUpType(Identifier, Info))2003            return Error(Tok.getLoc(), "unknown type");2004          SM.onCast(Info);2005          // Eat type and PTR.2006          consumeToken();2007          End = consumeToken();2008          break;2009        }2010      }2011      // Register, or (MASM only) <register>.<field>2012      MCRegister Reg;2013      if (Tok.is(AsmToken::Identifier)) {2014        if (!ParseRegister(Reg, IdentLoc, End, /*RestoreOnFailure=*/true)) {2015          if (SM.onRegister(Reg, ErrMsg))2016            return Error(IdentLoc, ErrMsg);2017          break;2018        }2019        if (Parser.isParsingMasm()) {2020          const std::pair<StringRef, StringRef> IDField =2021              Tok.getString().split('.');2022          const StringRef ID = IDField.first, Field = IDField.second;2023          SMLoc IDEndLoc = SMLoc::getFromPointer(ID.data() + ID.size());2024          if (!Field.empty() &&2025              !MatchRegisterByName(Reg, ID, IdentLoc, IDEndLoc)) {2026            if (SM.onRegister(Reg, ErrMsg))2027              return Error(IdentLoc, ErrMsg);2028 2029            AsmFieldInfo Info;2030            SMLoc FieldStartLoc = SMLoc::getFromPointer(Field.data());2031            if (Parser.lookUpField(Field, Info))2032              return Error(FieldStartLoc, "unknown offset");2033            else if (SM.onPlus(ErrMsg))2034              return Error(getTok().getLoc(), ErrMsg);2035            else if (SM.onInteger(Info.Offset, ErrMsg))2036              return Error(IdentLoc, ErrMsg);2037            SM.setTypeInfo(Info.Type);2038 2039            End = consumeToken();2040            break;2041          }2042        }2043      }2044      // Operator synonymous ("not", "or" etc.)2045      bool ParseError = false;2046      if (ParseIntelNamedOperator(Identifier, SM, ParseError, End)) {2047        if (ParseError)2048          return true;2049        break;2050      }2051      if (Parser.isParsingMasm() &&2052          ParseMasmNamedOperator(Identifier, SM, ParseError, End)) {2053        if (ParseError)2054          return true;2055        break;2056      }2057      // Symbol reference, when parsing assembly content2058      InlineAsmIdentifierInfo Info;2059      AsmFieldInfo FieldInfo;2060      const MCExpr *Val;2061      if (isParsingMSInlineAsm() || Parser.isParsingMasm()) {2062        // MS Dot Operator expression2063        if (Identifier.contains('.') &&2064            (PrevTK == AsmToken::RBrac || PrevTK == AsmToken::RParen)) {2065          if (ParseIntelDotOperator(SM, End))2066            return true;2067          break;2068        }2069      }2070      if (isParsingMSInlineAsm()) {2071        // MS InlineAsm operators (TYPE/LENGTH/SIZE)2072        if (unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {2073          if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {2074            if (SM.onInteger(Val, ErrMsg))2075              return Error(IdentLoc, ErrMsg);2076          } else {2077            return true;2078          }2079          break;2080        }2081        // MS InlineAsm identifier2082        // Call parseIdentifier() to combine @ with the identifier behind it.2083        if (TK == AsmToken::At && Parser.parseIdentifier(Identifier))2084          return Error(IdentLoc, "expected identifier");2085        if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info, false, End))2086          return true;2087        else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.Type,2088                                     true, ErrMsg))2089          return Error(IdentLoc, ErrMsg);2090        break;2091      }2092      if (Parser.isParsingMasm()) {2093        if (unsigned OpKind = IdentifyMasmOperator(Identifier)) {2094          int64_t Val;2095          if (ParseMasmOperator(OpKind, Val))2096            return true;2097          if (SM.onInteger(Val, ErrMsg))2098            return Error(IdentLoc, ErrMsg);2099          break;2100        }2101        if (!getParser().lookUpType(Identifier, FieldInfo.Type)) {2102          // Field offset immediate; <TYPE>.<field specification>2103          Lex(); // eat type2104          bool EndDot = parseOptionalToken(AsmToken::Dot);2105          while (EndDot || (getTok().is(AsmToken::Identifier) &&2106                            getTok().getString().starts_with("."))) {2107            getParser().parseIdentifier(Identifier);2108            if (!EndDot)2109              Identifier.consume_front(".");2110            EndDot = Identifier.consume_back(".");2111            if (getParser().lookUpField(FieldInfo.Type.Name, Identifier,2112                                        FieldInfo)) {2113              SMLoc IDEnd =2114                  SMLoc::getFromPointer(Identifier.data() + Identifier.size());2115              return Error(IdentLoc, "Unable to lookup field reference!",2116                           SMRange(IdentLoc, IDEnd));2117            }2118            if (!EndDot)2119              EndDot = parseOptionalToken(AsmToken::Dot);2120          }2121          if (SM.onInteger(FieldInfo.Offset, ErrMsg))2122            return Error(IdentLoc, ErrMsg);2123          break;2124        }2125      }2126      if (getParser().parsePrimaryExpr(Val, End, &FieldInfo.Type)) {2127        return Error(Tok.getLoc(), "Unexpected identifier!");2128      } else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.Type,2129                                     false, ErrMsg)) {2130        return Error(IdentLoc, ErrMsg);2131      }2132      break;2133    }2134    case AsmToken::Integer: {2135      // Look for 'b' or 'f' following an Integer as a directional label2136      SMLoc Loc = getTok().getLoc();2137      int64_t IntVal = getTok().getIntVal();2138      End = consumeToken();2139      UpdateLocLex = false;2140      if (getLexer().getKind() == AsmToken::Identifier) {2141        StringRef IDVal = getTok().getString();2142        if (IDVal == "f" || IDVal == "b") {2143          MCSymbol *Sym =2144              getContext().getDirectionalLocalSymbol(IntVal, IDVal == "b");2145          auto Variant = X86::S_None;2146          const MCExpr *Val =2147              MCSymbolRefExpr::create(Sym, Variant, getContext());2148          if (IDVal == "b" && Sym->isUndefined())2149            return Error(Loc, "invalid reference to undefined symbol");2150          StringRef Identifier = Sym->getName();2151          InlineAsmIdentifierInfo Info;2152          AsmTypeInfo Type;2153          if (SM.onIdentifierExpr(Val, Identifier, Info, Type,2154                                  isParsingMSInlineAsm(), ErrMsg))2155            return Error(Loc, ErrMsg);2156          End = consumeToken();2157        } else {2158          if (SM.onInteger(IntVal, ErrMsg))2159            return Error(Loc, ErrMsg);2160        }2161      } else {2162        if (SM.onInteger(IntVal, ErrMsg))2163          return Error(Loc, ErrMsg);2164      }2165      break;2166    }2167    case AsmToken::Plus:2168      if (SM.onPlus(ErrMsg))2169        return Error(getTok().getLoc(), ErrMsg);2170      break;2171    case AsmToken::Minus:2172      if (SM.onMinus(ErrMsg))2173        return Error(getTok().getLoc(), ErrMsg);2174      break;2175    case AsmToken::Tilde:   SM.onNot(); break;2176    case AsmToken::Star:    SM.onStar(); break;2177    case AsmToken::Slash:   SM.onDivide(); break;2178    case AsmToken::Percent: SM.onMod(); break;2179    case AsmToken::Pipe:    SM.onOr(); break;2180    case AsmToken::Caret:   SM.onXor(); break;2181    case AsmToken::Amp:     SM.onAnd(); break;2182    case AsmToken::LessLess:2183                            SM.onLShift(); break;2184    case AsmToken::GreaterGreater:2185                            SM.onRShift(); break;2186    case AsmToken::LBrac:2187      if (SM.onLBrac())2188        return Error(Tok.getLoc(), "unexpected bracket encountered");2189      tryParseOperandIdx(PrevTK, SM);2190      break;2191    case AsmToken::RBrac:2192      if (SM.onRBrac(ErrMsg)) {2193        return Error(Tok.getLoc(), ErrMsg);2194      }2195      break;2196    case AsmToken::LParen:  SM.onLParen(); break;2197    case AsmToken::RParen:2198      if (SM.onRParen(ErrMsg)) {2199        return Error(Tok.getLoc(), ErrMsg);2200      }2201      break;2202    }2203    if (SM.hadError())2204      return Error(Tok.getLoc(), "unknown token in expression");2205 2206    if (!Done && UpdateLocLex)2207      End = consumeToken();2208 2209    PrevTK = TK;2210  }2211  return false;2212}2213 2214void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &SM,2215                                          SMLoc Start, SMLoc End) {2216  SMLoc Loc = Start;2217  unsigned ExprLen = End.getPointer() - Start.getPointer();2218  // Skip everything before a symbol displacement (if we have one)2219  if (SM.getSym() && !SM.isOffsetOperator()) {2220    StringRef SymName = SM.getSymName();2221    if (unsigned Len = SymName.data() - Start.getPointer())2222      InstInfo->AsmRewrites->emplace_back(AOK_Skip, Start, Len);2223    Loc = SMLoc::getFromPointer(SymName.data() + SymName.size());2224    ExprLen = End.getPointer() - (SymName.data() + SymName.size());2225    // If we have only a symbol than there's no need for complex rewrite,2226    // simply skip everything after it2227    if (!(SM.getBaseReg() || SM.getIndexReg() || SM.getImm())) {2228      if (ExprLen)2229        InstInfo->AsmRewrites->emplace_back(AOK_Skip, Loc, ExprLen);2230      return;2231    }2232  }2233  // Build an Intel Expression rewrite2234  StringRef BaseRegStr;2235  StringRef IndexRegStr;2236  StringRef OffsetNameStr;2237  if (SM.getBaseReg())2238    BaseRegStr = X86IntelInstPrinter::getRegisterName(SM.getBaseReg());2239  if (SM.getIndexReg())2240    IndexRegStr = X86IntelInstPrinter::getRegisterName(SM.getIndexReg());2241  if (SM.isOffsetOperator())2242    OffsetNameStr = SM.getSymName();2243  // Emit it2244  IntelExpr Expr(BaseRegStr, IndexRegStr, SM.getScale(), OffsetNameStr,2245                 SM.getImm(), SM.isMemExpr());2246  InstInfo->AsmRewrites->emplace_back(Loc, ExprLen, Expr);2247}2248 2249// Inline assembly may use variable names with namespace alias qualifiers.2250bool X86AsmParser::ParseIntelInlineAsmIdentifier(2251    const MCExpr *&Val, StringRef &Identifier, InlineAsmIdentifierInfo &Info,2252    bool IsUnevaluatedOperand, SMLoc &End, bool IsParsingOffsetOperator) {2253  MCAsmParser &Parser = getParser();2254  assert(isParsingMSInlineAsm() && "Expected to be parsing inline assembly.");2255  Val = nullptr;2256 2257  StringRef LineBuf(Identifier.data());2258  SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);2259 2260  const AsmToken &Tok = Parser.getTok();2261  SMLoc Loc = Tok.getLoc();2262 2263  // Advance the token stream until the end of the current token is2264  // after the end of what the frontend claimed.2265  const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size();2266  do {2267    End = Tok.getEndLoc();2268    getLexer().Lex();2269  } while (End.getPointer() < EndPtr);2270  Identifier = LineBuf;2271 2272  // The frontend should end parsing on an assembler token boundary, unless it2273  // failed parsing.2274  assert((End.getPointer() == EndPtr ||2275          Info.isKind(InlineAsmIdentifierInfo::IK_Invalid)) &&2276          "frontend claimed part of a token?");2277 2278  // If the identifier lookup was unsuccessful, assume that we are dealing with2279  // a label.2280  if (Info.isKind(InlineAsmIdentifierInfo::IK_Invalid)) {2281    StringRef InternalName =2282      SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),2283                                         Loc, false);2284    assert(InternalName.size() && "We should have an internal name here.");2285    // Push a rewrite for replacing the identifier name with the internal name,2286    // unless we are parsing the operand of an offset operator2287    if (!IsParsingOffsetOperator)2288      InstInfo->AsmRewrites->emplace_back(AOK_Label, Loc, Identifier.size(),2289                                          InternalName);2290    else2291      Identifier = InternalName;2292  } else if (Info.isKind(InlineAsmIdentifierInfo::IK_EnumVal))2293    return false;2294  // Create the symbol reference.2295  MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);2296  auto Variant = X86::S_None;2297  Val = MCSymbolRefExpr::create(Sym, Variant, getParser().getContext());2298  return false;2299}2300 2301//ParseRoundingModeOp - Parse AVX-512 rounding mode operand2302bool X86AsmParser::ParseRoundingModeOp(SMLoc Start, OperandVector &Operands) {2303  MCAsmParser &Parser = getParser();2304  const AsmToken &Tok = Parser.getTok();2305  // Eat "{" and mark the current place.2306  const SMLoc consumedToken = consumeToken();2307  if (Tok.isNot(AsmToken::Identifier))2308    return Error(Tok.getLoc(), "Expected an identifier after {");2309  if (Tok.getIdentifier().starts_with("r")) {2310    int rndMode = StringSwitch<int>(Tok.getIdentifier())2311      .Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)2312      .Case("rd", X86::STATIC_ROUNDING::TO_NEG_INF)2313      .Case("ru", X86::STATIC_ROUNDING::TO_POS_INF)2314      .Case("rz", X86::STATIC_ROUNDING::TO_ZERO)2315      .Default(-1);2316    if (-1 == rndMode)2317      return Error(Tok.getLoc(), "Invalid rounding mode.");2318     Parser.Lex();  // Eat "r*" of r*-sae2319    if (!getLexer().is(AsmToken::Minus))2320      return Error(Tok.getLoc(), "Expected - at this point");2321    Parser.Lex();  // Eat "-"2322    Parser.Lex();  // Eat the sae2323    if (!getLexer().is(AsmToken::RCurly))2324      return Error(Tok.getLoc(), "Expected } at this point");2325    SMLoc End = Tok.getEndLoc();2326    Parser.Lex();  // Eat "}"2327    const MCExpr *RndModeOp =2328      MCConstantExpr::create(rndMode, Parser.getContext());2329    Operands.push_back(X86Operand::CreateImm(RndModeOp, Start, End));2330    return false;2331  }2332  if (Tok.getIdentifier() == "sae") {2333    Parser.Lex();  // Eat the sae2334    if (!getLexer().is(AsmToken::RCurly))2335      return Error(Tok.getLoc(), "Expected } at this point");2336    Parser.Lex();  // Eat "}"2337    Operands.push_back(X86Operand::CreateToken("{sae}", consumedToken));2338    return false;2339  }2340  return Error(Tok.getLoc(), "unknown token in expression");2341}2342 2343/// Parse condtional flags for CCMP/CTEST, e.g {dfv=of,sf,zf,cf} right after2344/// mnemonic.2345bool X86AsmParser::parseCFlagsOp(OperandVector &Operands) {2346  MCAsmParser &Parser = getParser();2347  AsmToken Tok = Parser.getTok();2348  const SMLoc Start = Tok.getLoc();2349  if (!Tok.is(AsmToken::LCurly))2350    return Error(Tok.getLoc(), "Expected { at this point");2351  Parser.Lex(); // Eat "{"2352  Tok = Parser.getTok();2353  if (Tok.getIdentifier().lower() != "dfv")2354    return Error(Tok.getLoc(), "Expected dfv at this point");2355  Parser.Lex(); // Eat "dfv"2356  Tok = Parser.getTok();2357  if (!Tok.is(AsmToken::Equal))2358    return Error(Tok.getLoc(), "Expected = at this point");2359  Parser.Lex(); // Eat "="2360 2361  Tok = Parser.getTok();2362  SMLoc End;2363  if (Tok.is(AsmToken::RCurly)) {2364    End = Tok.getEndLoc();2365    Operands.push_back(X86Operand::CreateImm(2366        MCConstantExpr::create(0, Parser.getContext()), Start, End));2367    Parser.Lex(); // Eat "}"2368    return false;2369  }2370  unsigned CFlags = 0;2371  for (unsigned I = 0; I < 4; ++I) {2372    Tok = Parser.getTok();2373    unsigned CFlag = StringSwitch<unsigned>(Tok.getIdentifier().lower())2374                         .Case("of", 0x8)2375                         .Case("sf", 0x4)2376                         .Case("zf", 0x2)2377                         .Case("cf", 0x1)2378                         .Default(~0U);2379    if (CFlag == ~0U)2380      return Error(Tok.getLoc(), "Invalid conditional flags");2381 2382    if (CFlags & CFlag)2383      return Error(Tok.getLoc(), "Duplicated conditional flag");2384    CFlags |= CFlag;2385 2386    Parser.Lex(); // Eat one conditional flag2387    Tok = Parser.getTok();2388    if (Tok.is(AsmToken::RCurly)) {2389      End = Tok.getEndLoc();2390      Operands.push_back(X86Operand::CreateImm(2391          MCConstantExpr::create(CFlags, Parser.getContext()), Start, End));2392      Parser.Lex(); // Eat "}"2393      return false;2394    } else if (I == 3) {2395      return Error(Tok.getLoc(), "Expected } at this point");2396    } else if (Tok.isNot(AsmToken::Comma)) {2397      return Error(Tok.getLoc(), "Expected } or , at this point");2398    }2399    Parser.Lex(); // Eat ","2400  }2401  llvm_unreachable("Unexpected control flow");2402}2403 2404/// Parse the '.' operator.2405bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &SM,2406                                         SMLoc &End) {2407  const AsmToken &Tok = getTok();2408  AsmFieldInfo Info;2409 2410  // Drop the optional '.'.2411  StringRef DotDispStr = Tok.getString();2412  DotDispStr.consume_front(".");2413  bool TrailingDot = false;2414 2415  // .Imm gets lexed as a real.2416  if (Tok.is(AsmToken::Real)) {2417    APInt DotDisp;2418    if (DotDispStr.getAsInteger(10, DotDisp))2419      return Error(Tok.getLoc(), "Unexpected offset");2420    Info.Offset = DotDisp.getZExtValue();2421  } else if ((isParsingMSInlineAsm() || getParser().isParsingMasm()) &&2422             Tok.is(AsmToken::Identifier)) {2423    TrailingDot = DotDispStr.consume_back(".");2424    const std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');2425    const StringRef Base = BaseMember.first, Member = BaseMember.second;2426    if (getParser().lookUpField(SM.getType(), DotDispStr, Info) &&2427        getParser().lookUpField(SM.getSymName(), DotDispStr, Info) &&2428        getParser().lookUpField(DotDispStr, Info) &&2429        (!SemaCallback ||2430         SemaCallback->LookupInlineAsmField(Base, Member, Info.Offset)))2431      return Error(Tok.getLoc(), "Unable to lookup field reference!");2432  } else {2433    return Error(Tok.getLoc(), "Unexpected token type!");2434  }2435 2436  // Eat the DotExpression and update End2437  End = SMLoc::getFromPointer(DotDispStr.data());2438  const char *DotExprEndLoc = DotDispStr.data() + DotDispStr.size();2439  while (Tok.getLoc().getPointer() < DotExprEndLoc)2440    Lex();2441  if (TrailingDot)2442    getLexer().UnLex(AsmToken(AsmToken::Dot, "."));2443  SM.addImm(Info.Offset);2444  SM.setTypeInfo(Info.Type);2445  return false;2446}2447 2448/// Parse the 'offset' operator.2449/// This operator is used to specify the location of a given operand2450bool X86AsmParser::ParseIntelOffsetOperator(const MCExpr *&Val, StringRef &ID,2451                                            InlineAsmIdentifierInfo &Info,2452                                            SMLoc &End) {2453  // Eat offset, mark start of identifier.2454  SMLoc Start = Lex().getLoc();2455  ID = getTok().getString();2456  if (!isParsingMSInlineAsm()) {2457    if ((getTok().isNot(AsmToken::Identifier) &&2458         getTok().isNot(AsmToken::String)) ||2459        getParser().parsePrimaryExpr(Val, End, nullptr))2460      return Error(Start, "unexpected token!");2461  } else if (ParseIntelInlineAsmIdentifier(Val, ID, Info, false, End, true)) {2462    return Error(Start, "unable to lookup expression");2463  } else if (Info.isKind(InlineAsmIdentifierInfo::IK_EnumVal)) {2464    return Error(Start, "offset operator cannot yet handle constants");2465  }2466  return false;2467}2468 2469// Query a candidate string for being an Intel assembly operator2470// Report back its kind, or IOK_INVALID if does not evaluated as a known one2471unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(StringRef Name) {2472  return StringSwitch<unsigned>(Name)2473      .Cases({"TYPE", "type"}, IOK_TYPE)2474      .Cases({"SIZE", "size"}, IOK_SIZE)2475      .Cases({"LENGTH", "length"}, IOK_LENGTH)2476      .Default(IOK_INVALID);2477}2478 2479/// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators.  The LENGTH operator2480/// returns the number of elements in an array.  It returns the value 1 for2481/// non-array variables.  The SIZE operator returns the size of a C or C++2482/// variable.  A variable's size is the product of its LENGTH and TYPE.  The2483/// TYPE operator returns the size of a C or C++ type or variable. If the2484/// variable is an array, TYPE returns the size of a single element.2485unsigned X86AsmParser::ParseIntelInlineAsmOperator(unsigned OpKind) {2486  MCAsmParser &Parser = getParser();2487  const AsmToken &Tok = Parser.getTok();2488  Parser.Lex(); // Eat operator.2489 2490  const MCExpr *Val = nullptr;2491  InlineAsmIdentifierInfo Info;2492  SMLoc Start = Tok.getLoc(), End;2493  StringRef Identifier = Tok.getString();2494  if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,2495                                    /*IsUnevaluatedOperand=*/true, End))2496    return 0;2497 2498  if (!Info.isKind(InlineAsmIdentifierInfo::IK_Var)) {2499    Error(Start, "unable to lookup expression");2500    return 0;2501  }2502 2503  unsigned CVal = 0;2504  switch(OpKind) {2505  default: llvm_unreachable("Unexpected operand kind!");2506  case IOK_LENGTH: CVal = Info.Var.Length; break;2507  case IOK_SIZE: CVal = Info.Var.Size; break;2508  case IOK_TYPE: CVal = Info.Var.Type; break;2509  }2510 2511  return CVal;2512}2513 2514// Query a candidate string for being an Intel assembly operator2515// Report back its kind, or IOK_INVALID if does not evaluated as a known one2516unsigned X86AsmParser::IdentifyMasmOperator(StringRef Name) {2517  return StringSwitch<unsigned>(Name.lower())2518      .Case("type", MOK_TYPE)2519      .Cases({"size", "sizeof"}, MOK_SIZEOF)2520      .Cases({"length", "lengthof"}, MOK_LENGTHOF)2521      .Default(MOK_INVALID);2522}2523 2524/// Parse the 'LENGTHOF', 'SIZEOF', and 'TYPE' operators.  The LENGTHOF operator2525/// returns the number of elements in an array.  It returns the value 1 for2526/// non-array variables.  The SIZEOF operator returns the size of a type or2527/// variable in bytes.  A variable's size is the product of its LENGTH and TYPE.2528/// The TYPE operator returns the size of a variable. If the variable is an2529/// array, TYPE returns the size of a single element.2530bool X86AsmParser::ParseMasmOperator(unsigned OpKind, int64_t &Val) {2531  MCAsmParser &Parser = getParser();2532  SMLoc OpLoc = Parser.getTok().getLoc();2533  Parser.Lex(); // Eat operator.2534 2535  Val = 0;2536  if (OpKind == MOK_SIZEOF || OpKind == MOK_TYPE) {2537    // Check for SIZEOF(<type>) and TYPE(<type>).2538    bool InParens = Parser.getTok().is(AsmToken::LParen);2539    const AsmToken &IDTok = InParens ? getLexer().peekTok() : Parser.getTok();2540    AsmTypeInfo Type;2541    if (IDTok.is(AsmToken::Identifier) &&2542        !Parser.lookUpType(IDTok.getIdentifier(), Type)) {2543      Val = Type.Size;2544 2545      // Eat tokens.2546      if (InParens)2547        parseToken(AsmToken::LParen);2548      parseToken(AsmToken::Identifier);2549      if (InParens)2550        parseToken(AsmToken::RParen);2551    }2552  }2553 2554  if (!Val) {2555    IntelExprStateMachine SM;2556    SMLoc End, Start = Parser.getTok().getLoc();2557    if (ParseIntelExpression(SM, End))2558      return true;2559 2560    switch (OpKind) {2561    default:2562      llvm_unreachable("Unexpected operand kind!");2563    case MOK_SIZEOF:2564      Val = SM.getSize();2565      break;2566    case MOK_LENGTHOF:2567      Val = SM.getLength();2568      break;2569    case MOK_TYPE:2570      Val = SM.getElementSize();2571      break;2572    }2573 2574    if (!Val)2575      return Error(OpLoc, "expression has unknown type", SMRange(Start, End));2576  }2577 2578  return false;2579}2580 2581bool X86AsmParser::ParseIntelMemoryOperandSize(unsigned &Size,2582                                               StringRef *SizeStr) {2583  Size = StringSwitch<unsigned>(getTok().getString())2584             .Cases({"BYTE", "byte"}, 8)2585             .Cases({"WORD", "word"}, 16)2586             .Cases({"DWORD", "dword"}, 32)2587             .Cases({"FLOAT", "float"}, 32)2588             .Cases({"LONG", "long"}, 32)2589             .Cases({"FWORD", "fword"}, 48)2590             .Cases({"DOUBLE", "double"}, 64)2591             .Cases({"QWORD", "qword"}, 64)2592             .Cases({"MMWORD", "mmword"}, 64)2593             .Cases({"XWORD", "xword"}, 80)2594             .Cases({"TBYTE", "tbyte"}, 80)2595             .Cases({"XMMWORD", "xmmword"}, 128)2596             .Cases({"YMMWORD", "ymmword"}, 256)2597             .Cases({"ZMMWORD", "zmmword"}, 512)2598             .Default(0);2599  if (Size) {2600    if (SizeStr)2601      *SizeStr = getTok().getString();2602    const AsmToken &Tok = Lex(); // Eat operand size (e.g., byte, word).2603    if (!(Tok.getString() == "PTR" || Tok.getString() == "ptr"))2604      return Error(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");2605    Lex(); // Eat ptr.2606  }2607  return false;2608}2609 2610uint16_t RegSizeInBits(const MCRegisterInfo &MRI, MCRegister RegNo) {2611  if (X86MCRegisterClasses[X86::GR8RegClassID].contains(RegNo))2612    return 8;2613  if (X86MCRegisterClasses[X86::GR16RegClassID].contains(RegNo))2614    return 16;2615  if (X86MCRegisterClasses[X86::GR32RegClassID].contains(RegNo))2616    return 32;2617  if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))2618    return 64;2619  // Unknown register size2620  return 0;2621}2622 2623bool X86AsmParser::parseIntelOperand(OperandVector &Operands, StringRef Name) {2624  MCAsmParser &Parser = getParser();2625  const AsmToken &Tok = Parser.getTok();2626  SMLoc Start, End;2627 2628  // Parse optional Size directive.2629  unsigned Size;2630  StringRef SizeStr;2631  if (ParseIntelMemoryOperandSize(Size, &SizeStr))2632    return true;2633  bool PtrInOperand = bool(Size);2634 2635  Start = Tok.getLoc();2636 2637  // Rounding mode operand.2638  if (getLexer().is(AsmToken::LCurly))2639    return ParseRoundingModeOp(Start, Operands);2640 2641  // Register operand.2642  MCRegister RegNo;2643  if (Tok.is(AsmToken::Identifier) && !parseRegister(RegNo, Start, End)) {2644    if (RegNo == X86::RIP)2645      return Error(Start, "rip can only be used as a base register");2646    // A Register followed by ':' is considered a segment override2647    if (Tok.isNot(AsmToken::Colon)) {2648      if (PtrInOperand) {2649        if (!Parser.isParsingMasm())2650          return Error(Start, "expected memory operand after 'ptr', "2651                              "found register operand instead");2652 2653        // If we are parsing MASM, we are allowed to cast registers to their own2654        // sizes, but not to other types.2655        uint16_t RegSize =2656            RegSizeInBits(*getContext().getRegisterInfo(), RegNo);2657        if (RegSize == 0)2658          return Error(2659              Start,2660              "cannot cast register '" +2661                  StringRef(getContext().getRegisterInfo()->getName(RegNo)) +2662                  "'; its size is not easily defined.");2663        if (RegSize != Size)2664          return Error(2665              Start,2666              std::to_string(RegSize) + "-bit register '" +2667                  StringRef(getContext().getRegisterInfo()->getName(RegNo)) +2668                  "' cannot be used as a " + std::to_string(Size) + "-bit " +2669                  SizeStr.upper());2670      }2671      Operands.push_back(X86Operand::CreateReg(RegNo, Start, End));2672      return false;2673    }2674    // An alleged segment override. check if we have a valid segment register2675    if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))2676      return Error(Start, "invalid segment register");2677    // Eat ':' and update Start location2678    Start = Lex().getLoc();2679  }2680 2681  // Immediates and Memory2682  IntelExprStateMachine SM;2683  if (ParseIntelExpression(SM, End))2684    return true;2685 2686  if (isParsingMSInlineAsm())2687    RewriteIntelExpression(SM, Start, Tok.getLoc());2688 2689  int64_t Imm = SM.getImm();2690  const MCExpr *Disp = SM.getSym();2691  const MCExpr *ImmDisp = MCConstantExpr::create(Imm, getContext());2692  if (Disp && Imm)2693    Disp = MCBinaryExpr::createAdd(Disp, ImmDisp, getContext());2694  if (!Disp)2695    Disp = ImmDisp;2696 2697  // RegNo != 0 specifies a valid segment register,2698  // and we are parsing a segment override2699  if (!SM.isMemExpr() && !RegNo) {2700    if (isParsingMSInlineAsm() && SM.isOffsetOperator()) {2701      const InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();2702      if (Info.isKind(InlineAsmIdentifierInfo::IK_Var)) {2703        // Disp includes the address of a variable; make sure this is recorded2704        // for later handling.2705        Operands.push_back(X86Operand::CreateImm(Disp, Start, End,2706                                                 SM.getSymName(), Info.Var.Decl,2707                                                 Info.Var.IsGlobalLV));2708        return false;2709      }2710    }2711 2712    Operands.push_back(X86Operand::CreateImm(Disp, Start, End));2713    return false;2714  }2715 2716  StringRef ErrMsg;2717  MCRegister BaseReg = SM.getBaseReg();2718  MCRegister IndexReg = SM.getIndexReg();2719  if (IndexReg && BaseReg == X86::RIP)2720    BaseReg = MCRegister();2721  unsigned Scale = SM.getScale();2722  if (!PtrInOperand)2723    Size = SM.getElementSize() << 3;2724 2725  if (Scale == 0 && BaseReg != X86::ESP && BaseReg != X86::RSP &&2726      (IndexReg == X86::ESP || IndexReg == X86::RSP))2727    std::swap(BaseReg, IndexReg);2728 2729  // If BaseReg is a vector register and IndexReg is not, swap them unless2730  // Scale was specified in which case it would be an error.2731  if (Scale == 0 &&2732      !(X86MCRegisterClasses[X86::VR128XRegClassID].contains(IndexReg) ||2733        X86MCRegisterClasses[X86::VR256XRegClassID].contains(IndexReg) ||2734        X86MCRegisterClasses[X86::VR512RegClassID].contains(IndexReg)) &&2735      (X86MCRegisterClasses[X86::VR128XRegClassID].contains(BaseReg) ||2736       X86MCRegisterClasses[X86::VR256XRegClassID].contains(BaseReg) ||2737       X86MCRegisterClasses[X86::VR512RegClassID].contains(BaseReg)))2738    std::swap(BaseReg, IndexReg);2739 2740  if (Scale != 0 &&2741      X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg))2742    return Error(Start, "16-bit addresses cannot have a scale");2743 2744  // If there was no explicit scale specified, change it to 1.2745  if (Scale == 0)2746    Scale = 1;2747 2748  // If this is a 16-bit addressing mode with the base and index in the wrong2749  // order, swap them so CheckBaseRegAndIndexRegAndScale doesn't fail. It is2750  // shared with att syntax where order matters.2751  if ((BaseReg == X86::SI || BaseReg == X86::DI) &&2752      (IndexReg == X86::BX || IndexReg == X86::BP))2753    std::swap(BaseReg, IndexReg);2754 2755  if ((BaseReg || IndexReg) &&2756      CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, is64BitMode(),2757                                      ErrMsg))2758    return Error(Start, ErrMsg);2759  bool IsUnconditionalBranch =2760      Name.equals_insensitive("jmp") || Name.equals_insensitive("call");2761  if (isParsingMSInlineAsm())2762    return CreateMemForMSInlineAsm(RegNo, Disp, BaseReg, IndexReg, Scale,2763                                   IsUnconditionalBranch && is64BitMode(),2764                                   Start, End, Size, SM.getSymName(),2765                                   SM.getIdentifierInfo(), Operands);2766 2767  // When parsing x64 MS-style assembly, all non-absolute references to a named2768  // variable default to RIP-relative.2769  MCRegister DefaultBaseReg;2770  bool MaybeDirectBranchDest = true;2771 2772  if (Parser.isParsingMasm()) {2773    if (is64BitMode() &&2774        ((PtrInOperand && !IndexReg) || SM.getElementSize() > 0)) {2775      DefaultBaseReg = X86::RIP;2776    }2777    if (IsUnconditionalBranch) {2778      if (PtrInOperand) {2779        MaybeDirectBranchDest = false;2780        if (is64BitMode())2781          DefaultBaseReg = X86::RIP;2782      } else if (!BaseReg && !IndexReg && Disp &&2783                 Disp->getKind() == MCExpr::SymbolRef) {2784        if (is64BitMode()) {2785          if (SM.getSize() == 8) {2786            MaybeDirectBranchDest = false;2787            DefaultBaseReg = X86::RIP;2788          }2789        } else {2790          if (SM.getSize() == 4 || SM.getSize() == 2)2791            MaybeDirectBranchDest = false;2792        }2793      }2794    }2795  } else if (IsUnconditionalBranch) {2796    // Treat `call [offset fn_ref]` (or `jmp`) syntax as an error.2797    if (!PtrInOperand && SM.isOffsetOperator())2798      return Error(2799          Start, "`OFFSET` operator cannot be used in an unconditional branch");2800    if (PtrInOperand || SM.isBracketUsed())2801      MaybeDirectBranchDest = false;2802  }2803 2804  if ((BaseReg || IndexReg || RegNo || DefaultBaseReg))2805    Operands.push_back(X86Operand::CreateMem(2806        getPointerWidth(), RegNo, Disp, BaseReg, IndexReg, Scale, Start, End,2807        Size, DefaultBaseReg, /*SymName=*/StringRef(), /*OpDecl=*/nullptr,2808        /*FrontendSize=*/0, /*UseUpRegs=*/false, MaybeDirectBranchDest));2809  else2810    Operands.push_back(X86Operand::CreateMem(2811        getPointerWidth(), Disp, Start, End, Size, /*SymName=*/StringRef(),2812        /*OpDecl=*/nullptr, /*FrontendSize=*/0, /*UseUpRegs=*/false,2813        MaybeDirectBranchDest));2814  return false;2815}2816 2817bool X86AsmParser::parseATTOperand(OperandVector &Operands) {2818  MCAsmParser &Parser = getParser();2819  switch (getLexer().getKind()) {2820  case AsmToken::Dollar: {2821    // $42 or $ID -> immediate.2822    SMLoc Start = Parser.getTok().getLoc(), End;2823    Parser.Lex();2824    const MCExpr *Val;2825    // This is an immediate, so we should not parse a register. Do a precheck2826    // for '%' to supercede intra-register parse errors.2827    SMLoc L = Parser.getTok().getLoc();2828    if (check(getLexer().is(AsmToken::Percent), L,2829              "expected immediate expression") ||2830        getParser().parseExpression(Val, End) ||2831        check(isa<X86MCExpr>(Val), L, "expected immediate expression"))2832      return true;2833    Operands.push_back(X86Operand::CreateImm(Val, Start, End));2834    return false;2835  }2836  case AsmToken::LCurly: {2837    SMLoc Start = Parser.getTok().getLoc();2838    return ParseRoundingModeOp(Start, Operands);2839  }2840  default: {2841    // This a memory operand or a register. We have some parsing complications2842    // as a '(' may be part of an immediate expression or the addressing mode2843    // block. This is complicated by the fact that an assembler-level variable2844    // may refer either to a register or an immediate expression.2845 2846    SMLoc Loc = Parser.getTok().getLoc(), EndLoc;2847    const MCExpr *Expr = nullptr;2848    MCRegister Reg;2849    if (getLexer().isNot(AsmToken::LParen)) {2850      // No '(' so this is either a displacement expression or a register.2851      if (Parser.parseExpression(Expr, EndLoc))2852        return true;2853      if (auto *RE = dyn_cast<X86MCExpr>(Expr)) {2854        // Segment Register. Reset Expr and copy value to register.2855        Expr = nullptr;2856        Reg = RE->getReg();2857 2858        // Check the register.2859        if (Reg == X86::EIZ || Reg == X86::RIZ)2860          return Error(2861              Loc, "%eiz and %riz can only be used as index registers",2862              SMRange(Loc, EndLoc));2863        if (Reg == X86::RIP)2864          return Error(Loc, "%rip can only be used as a base register",2865                       SMRange(Loc, EndLoc));2866        // Return register that are not segment prefixes immediately.2867        if (!Parser.parseOptionalToken(AsmToken::Colon)) {2868          Operands.push_back(X86Operand::CreateReg(Reg, Loc, EndLoc));2869          return false;2870        }2871        if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(Reg))2872          return Error(Loc, "invalid segment register");2873        // Accept a '*' absolute memory reference after the segment. Place it2874        // before the full memory operand.2875        if (getLexer().is(AsmToken::Star))2876          Operands.push_back(X86Operand::CreateToken("*", consumeToken()));2877      }2878    }2879    // This is a Memory operand.2880    return ParseMemOperand(Reg, Expr, Loc, EndLoc, Operands);2881  }2882  }2883}2884 2885// X86::COND_INVALID if not a recognized condition code or alternate mnemonic,2886// otherwise the EFLAGS Condition Code enumerator.2887X86::CondCode X86AsmParser::ParseConditionCode(StringRef CC) {2888  return StringSwitch<X86::CondCode>(CC)2889      .Case("o", X86::COND_O)            // Overflow2890      .Case("no", X86::COND_NO)          // No Overflow2891      .Cases({"b", "nae"}, X86::COND_B)  // Below/Neither Above nor Equal2892      .Cases({"ae", "nb"}, X86::COND_AE) // Above or Equal/Not Below2893      .Cases({"e", "z"}, X86::COND_E)    // Equal/Zero2894      .Cases({"ne", "nz"}, X86::COND_NE) // Not Equal/Not Zero2895      .Cases({"be", "na"}, X86::COND_BE) // Below or Equal/Not Above2896      .Cases({"a", "nbe"}, X86::COND_A)  // Above/Neither Below nor Equal2897      .Case("s", X86::COND_S)            // Sign2898      .Case("ns", X86::COND_NS)          // No Sign2899      .Cases({"p", "pe"}, X86::COND_P)   // Parity/Parity Even2900      .Cases({"np", "po"}, X86::COND_NP) // No Parity/Parity Odd2901      .Cases({"l", "nge"}, X86::COND_L)  // Less/Neither Greater nor Equal2902      .Cases({"ge", "nl"}, X86::COND_GE) // Greater or Equal/Not Less2903      .Cases({"le", "ng"}, X86::COND_LE) // Less or Equal/Not Greater2904      .Cases({"g", "nle"}, X86::COND_G)  // Greater/Neither Less nor Equal2905      .Default(X86::COND_INVALID);2906}2907 2908// true on failure, false otherwise2909// If no {z} mark was found - Parser doesn't advance2910bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z, SMLoc StartLoc) {2911  MCAsmParser &Parser = getParser();2912  // Assuming we are just pass the '{' mark, quering the next token2913  // Searched for {z}, but none was found. Return false, as no parsing error was2914  // encountered2915  if (!(getLexer().is(AsmToken::Identifier) &&2916        (getLexer().getTok().getIdentifier() == "z")))2917    return false;2918  Parser.Lex(); // Eat z2919  // Query and eat the '}' mark2920  if (!getLexer().is(AsmToken::RCurly))2921    return Error(getLexer().getLoc(), "Expected } at this point");2922  Parser.Lex(); // Eat '}'2923  // Assign Z with the {z} mark operand2924  Z = X86Operand::CreateToken("{z}", StartLoc);2925  return false;2926}2927 2928// true on failure, false otherwise2929bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands) {2930  MCAsmParser &Parser = getParser();2931  if (getLexer().is(AsmToken::LCurly)) {2932    // Eat "{" and mark the current place.2933    const SMLoc consumedToken = consumeToken();2934    // Distinguish {1to<NUM>} from {%k<NUM>}.2935    if(getLexer().is(AsmToken::Integer)) {2936      // Parse memory broadcasting ({1to<NUM>}).2937      if (getLexer().getTok().getIntVal() != 1)2938        return TokError("Expected 1to<NUM> at this point");2939      StringRef Prefix = getLexer().getTok().getString();2940      Parser.Lex(); // Eat first token of 1to82941      if (!getLexer().is(AsmToken::Identifier))2942        return TokError("Expected 1to<NUM> at this point");2943      // Recognize only reasonable suffixes.2944      SmallVector<char, 5> BroadcastVector;2945      StringRef BroadcastString = (Prefix + getLexer().getTok().getIdentifier())2946                                      .toStringRef(BroadcastVector);2947      if (!BroadcastString.starts_with("1to"))2948        return TokError("Expected 1to<NUM> at this point");2949      const char *BroadcastPrimitive =2950          StringSwitch<const char *>(BroadcastString)2951              .Case("1to2", "{1to2}")2952              .Case("1to4", "{1to4}")2953              .Case("1to8", "{1to8}")2954              .Case("1to16", "{1to16}")2955              .Case("1to32", "{1to32}")2956              .Default(nullptr);2957      if (!BroadcastPrimitive)2958        return TokError("Invalid memory broadcast primitive.");2959      Parser.Lex(); // Eat trailing token of 1toN2960      if (!getLexer().is(AsmToken::RCurly))2961        return TokError("Expected } at this point");2962      Parser.Lex();  // Eat "}"2963      Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,2964                                                 consumedToken));2965      // No AVX512 specific primitives can pass2966      // after memory broadcasting, so return.2967      return false;2968    } else {2969      // Parse either {k}{z}, {z}{k}, {k} or {z}2970      // last one have no meaning, but GCC accepts it2971      // Currently, we're just pass a '{' mark2972      std::unique_ptr<X86Operand> Z;2973      if (ParseZ(Z, consumedToken))2974        return true;2975      // Reaching here means that parsing of the allegadly '{z}' mark yielded2976      // no errors.2977      // Query for the need of further parsing for a {%k<NUM>} mark2978      if (!Z || getLexer().is(AsmToken::LCurly)) {2979        SMLoc StartLoc = Z ? consumeToken() : consumedToken;2980        // Parse an op-mask register mark ({%k<NUM>}), which is now to be2981        // expected2982        MCRegister RegNo;2983        SMLoc RegLoc;2984        if (!parseRegister(RegNo, RegLoc, StartLoc) &&2985            X86MCRegisterClasses[X86::VK1RegClassID].contains(RegNo)) {2986          if (RegNo == X86::K0)2987            return Error(RegLoc, "Register k0 can't be used as write mask");2988          if (!getLexer().is(AsmToken::RCurly))2989            return Error(getLexer().getLoc(), "Expected } at this point");2990          Operands.push_back(X86Operand::CreateToken("{", StartLoc));2991          Operands.push_back(2992              X86Operand::CreateReg(RegNo, StartLoc, StartLoc));2993          Operands.push_back(X86Operand::CreateToken("}", consumeToken()));2994        } else2995          return Error(getLexer().getLoc(),2996                        "Expected an op-mask register at this point");2997        // {%k<NUM>} mark is found, inquire for {z}2998        if (getLexer().is(AsmToken::LCurly) && !Z) {2999          // Have we've found a parsing error, or found no (expected) {z} mark3000          // - report an error3001          if (ParseZ(Z, consumeToken()) || !Z)3002            return Error(getLexer().getLoc(),3003                         "Expected a {z} mark at this point");3004 3005        }3006        // '{z}' on its own is meaningless, hence should be ignored.3007        // on the contrary - have it been accompanied by a K register,3008        // allow it.3009        if (Z)3010          Operands.push_back(std::move(Z));3011      }3012    }3013  }3014  return false;3015}3016 3017/// ParseMemOperand: 'seg : disp(basereg, indexreg, scale)'.  The '%ds:' prefix3018/// has already been parsed if present. disp may be provided as well.3019bool X86AsmParser::ParseMemOperand(MCRegister SegReg, const MCExpr *Disp,3020                                   SMLoc StartLoc, SMLoc EndLoc,3021                                   OperandVector &Operands) {3022  MCAsmParser &Parser = getParser();3023  SMLoc Loc;3024  // Based on the initial passed values, we may be in any of these cases, we are3025  // in one of these cases (with current position (*)):3026 3027  //   1. seg : * disp  (base-index-scale-expr)3028  //   2. seg : *(disp) (base-index-scale-expr)3029  //   3. seg :       *(base-index-scale-expr)3030  //   4.        disp  *(base-index-scale-expr)3031  //   5.      *(disp)  (base-index-scale-expr)3032  //   6.             *(base-index-scale-expr)3033  //   7.  disp *3034  //   8. *(disp)3035 3036  // If we do not have an displacement yet, check if we're in cases 4 or 6 by3037  // checking if the first object after the parenthesis is a register (or an3038  // identifier referring to a register) and parse the displacement or default3039  // to 0 as appropriate.3040  auto isAtMemOperand = [this]() {3041    if (this->getLexer().isNot(AsmToken::LParen))3042      return false;3043    AsmToken Buf[2];3044    StringRef Id;3045    auto TokCount = this->getLexer().peekTokens(Buf, true);3046    if (TokCount == 0)3047      return false;3048    switch (Buf[0].getKind()) {3049    case AsmToken::Percent:3050    case AsmToken::Comma:3051      return true;3052    // These lower cases are doing a peekIdentifier.3053    case AsmToken::At:3054    case AsmToken::Dollar:3055      if ((TokCount > 1) &&3056          (Buf[1].is(AsmToken::Identifier) || Buf[1].is(AsmToken::String)) &&3057          (Buf[0].getLoc().getPointer() + 1 == Buf[1].getLoc().getPointer()))3058        Id = StringRef(Buf[0].getLoc().getPointer(),3059                       Buf[1].getIdentifier().size() + 1);3060      break;3061    case AsmToken::Identifier:3062    case AsmToken::String:3063      Id = Buf[0].getIdentifier();3064      break;3065    default:3066      return false;3067    }3068    // We have an ID. Check if it is bound to a register.3069    if (!Id.empty()) {3070      MCSymbol *Sym = this->getContext().getOrCreateSymbol(Id);3071      if (Sym->isVariable()) {3072        auto V = Sym->getVariableValue();3073        return isa<X86MCExpr>(V);3074      }3075    }3076    return false;3077  };3078 3079  if (!Disp) {3080    // Parse immediate if we're not at a mem operand yet.3081    if (!isAtMemOperand()) {3082      if (Parser.parseTokenLoc(Loc) || Parser.parseExpression(Disp, EndLoc))3083        return true;3084      assert(!isa<X86MCExpr>(Disp) && "Expected non-register here.");3085    } else {3086      // Disp is implicitly zero if we haven't parsed it yet.3087      Disp = MCConstantExpr::create(0, Parser.getContext());3088    }3089  }3090 3091  // We are now either at the end of the operand or at the '(' at the start of a3092  // base-index-scale-expr.3093 3094  if (!parseOptionalToken(AsmToken::LParen)) {3095    if (!SegReg)3096      Operands.push_back(3097          X86Operand::CreateMem(getPointerWidth(), Disp, StartLoc, EndLoc));3098    else3099      Operands.push_back(X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,3100                                               0, 0, 1, StartLoc, EndLoc));3101    return false;3102  }3103 3104  // If we reached here, then eat the '(' and Process3105  // the rest of the memory operand.3106  MCRegister BaseReg, IndexReg;3107  unsigned Scale = 1;3108  SMLoc BaseLoc = getLexer().getLoc();3109  const MCExpr *E;3110  StringRef ErrMsg;3111 3112  // Parse BaseReg if one is provided.3113  if (getLexer().isNot(AsmToken::Comma) && getLexer().isNot(AsmToken::RParen)) {3114    if (Parser.parseExpression(E, EndLoc) ||3115        check(!isa<X86MCExpr>(E), BaseLoc, "expected register here"))3116      return true;3117 3118    // Check the register.3119    BaseReg = cast<X86MCExpr>(E)->getReg();3120    if (BaseReg == X86::EIZ || BaseReg == X86::RIZ)3121      return Error(BaseLoc, "eiz and riz can only be used as index registers",3122                   SMRange(BaseLoc, EndLoc));3123  }3124 3125  if (parseOptionalToken(AsmToken::Comma)) {3126    // Following the comma we should have either an index register, or a scale3127    // value. We don't support the later form, but we want to parse it3128    // correctly.3129    //3130    // Even though it would be completely consistent to support syntax like3131    // "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.3132    if (getLexer().isNot(AsmToken::RParen)) {3133      if (Parser.parseTokenLoc(Loc) || Parser.parseExpression(E, EndLoc))3134        return true;3135 3136      if (!isa<X86MCExpr>(E)) {3137        // We've parsed an unexpected Scale Value instead of an index3138        // register. Interpret it as an absolute.3139        int64_t ScaleVal;3140        if (!E->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr()))3141          return Error(Loc, "expected absolute expression");3142        if (ScaleVal != 1)3143          Warning(Loc, "scale factor without index register is ignored");3144        Scale = 1;3145      } else { // IndexReg Found.3146        IndexReg = cast<X86MCExpr>(E)->getReg();3147 3148        if (BaseReg == X86::RIP)3149          return Error(Loc,3150                       "%rip as base register can not have an index register");3151        if (IndexReg == X86::RIP)3152          return Error(Loc, "%rip is not allowed as an index register");3153 3154        if (parseOptionalToken(AsmToken::Comma)) {3155          // Parse the scale amount:3156          //  ::= ',' [scale-expression]3157 3158          // A scale amount without an index is ignored.3159          if (getLexer().isNot(AsmToken::RParen)) {3160            int64_t ScaleVal;3161            if (Parser.parseTokenLoc(Loc) ||3162                Parser.parseAbsoluteExpression(ScaleVal))3163              return Error(Loc, "expected scale expression");3164            Scale = (unsigned)ScaleVal;3165            // Validate the scale amount.3166            if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&3167                Scale != 1)3168              return Error(Loc, "scale factor in 16-bit address must be 1");3169            if (checkScale(Scale, ErrMsg))3170              return Error(Loc, ErrMsg);3171          }3172        }3173      }3174    }3175  }3176 3177  // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.3178  if (parseToken(AsmToken::RParen, "unexpected token in memory operand"))3179    return true;3180 3181  // This is to support otherwise illegal operand (%dx) found in various3182  // unofficial manuals examples (e.g. "out[s]?[bwl]? %al, (%dx)") and must now3183  // be supported. Mark such DX variants separately fix only in special cases.3184  if (BaseReg == X86::DX && !IndexReg && Scale == 1 && !SegReg &&3185      isa<MCConstantExpr>(Disp) &&3186      cast<MCConstantExpr>(Disp)->getValue() == 0) {3187    Operands.push_back(X86Operand::CreateDXReg(BaseLoc, BaseLoc));3188    return false;3189  }3190 3191  if (CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, is64BitMode(),3192                                      ErrMsg))3193    return Error(BaseLoc, ErrMsg);3194 3195  // If the displacement is a constant, check overflows. For 64-bit addressing,3196  // gas requires isInt<32> and otherwise reports an error. For others, gas3197  // reports a warning and allows a wider range. E.g. gas allows3198  // [-0xffffffff,0xffffffff] for 32-bit addressing (e.g. Linux kernel uses3199  // `leal -__PAGE_OFFSET(%ecx),%esp` where __PAGE_OFFSET is 0xc0000000).3200  if (BaseReg || IndexReg) {3201    if (auto CE = dyn_cast<MCConstantExpr>(Disp)) {3202      auto Imm = CE->getValue();3203      bool Is64 = X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) ||3204                  X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg);3205      bool Is16 = X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg);3206      if (Is64) {3207        if (!isInt<32>(Imm))3208          return Error(BaseLoc, "displacement " + Twine(Imm) +3209                                    " is not within [-2147483648, 2147483647]");3210      } else if (!Is16) {3211        if (!isUInt<32>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {3212          Warning(BaseLoc, "displacement " + Twine(Imm) +3213                               " shortened to 32-bit signed " +3214                               Twine(static_cast<int32_t>(Imm)));3215        }3216      } else if (!isUInt<16>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {3217        Warning(BaseLoc, "displacement " + Twine(Imm) +3218                             " shortened to 16-bit signed " +3219                             Twine(static_cast<int16_t>(Imm)));3220      }3221    }3222  }3223 3224  if (SegReg || BaseReg || IndexReg)3225    Operands.push_back(X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,3226                                             BaseReg, IndexReg, Scale, StartLoc,3227                                             EndLoc));3228  else3229    Operands.push_back(3230        X86Operand::CreateMem(getPointerWidth(), Disp, StartLoc, EndLoc));3231  return false;3232}3233 3234// Parse either a standard primary expression or a register.3235bool X86AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {3236  MCAsmParser &Parser = getParser();3237  // See if this is a register first.3238  if (getTok().is(AsmToken::Percent) ||3239      (isParsingIntelSyntax() && getTok().is(AsmToken::Identifier) &&3240       MatchRegisterName(Parser.getTok().getString()))) {3241    SMLoc StartLoc = Parser.getTok().getLoc();3242    MCRegister RegNo;3243    if (parseRegister(RegNo, StartLoc, EndLoc))3244      return true;3245    Res = X86MCExpr::create(RegNo, Parser.getContext());3246    return false;3247  }3248  return Parser.parsePrimaryExpr(Res, EndLoc, nullptr);3249}3250 3251bool X86AsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,3252                                    SMLoc NameLoc, OperandVector &Operands) {3253  MCAsmParser &Parser = getParser();3254  InstInfo = &Info;3255 3256  // Reset the forced VEX encoding.3257  ForcedOpcodePrefix = OpcodePrefix_Default;3258  ForcedDispEncoding = DispEncoding_Default;3259  UseApxExtendedReg = false;3260  ForcedNoFlag = false;3261 3262  // Parse pseudo prefixes.3263  while (true) {3264    if (Name == "{") {3265      if (getLexer().isNot(AsmToken::Identifier))3266        return Error(Parser.getTok().getLoc(), "Unexpected token after '{'");3267      std::string Prefix = Parser.getTok().getString().lower();3268      Parser.Lex(); // Eat identifier.3269      if (getLexer().isNot(AsmToken::RCurly))3270        return Error(Parser.getTok().getLoc(), "Expected '}'");3271      Parser.Lex(); // Eat curly.3272 3273      if (Prefix == "rex")3274        ForcedOpcodePrefix = OpcodePrefix_REX;3275      else if (Prefix == "rex2")3276        ForcedOpcodePrefix = OpcodePrefix_REX2;3277      else if (Prefix == "vex")3278        ForcedOpcodePrefix = OpcodePrefix_VEX;3279      else if (Prefix == "vex2")3280        ForcedOpcodePrefix = OpcodePrefix_VEX2;3281      else if (Prefix == "vex3")3282        ForcedOpcodePrefix = OpcodePrefix_VEX3;3283      else if (Prefix == "evex")3284        ForcedOpcodePrefix = OpcodePrefix_EVEX;3285      else if (Prefix == "disp8")3286        ForcedDispEncoding = DispEncoding_Disp8;3287      else if (Prefix == "disp32")3288        ForcedDispEncoding = DispEncoding_Disp32;3289      else if (Prefix == "nf")3290        ForcedNoFlag = true;3291      else3292        return Error(NameLoc, "unknown prefix");3293 3294      NameLoc = Parser.getTok().getLoc();3295      if (getLexer().is(AsmToken::LCurly)) {3296        Parser.Lex();3297        Name = "{";3298      } else {3299        if (getLexer().isNot(AsmToken::Identifier))3300          return Error(Parser.getTok().getLoc(), "Expected identifier");3301        // FIXME: The mnemonic won't match correctly if its not in lower case.3302        Name = Parser.getTok().getString();3303        Parser.Lex();3304      }3305      continue;3306    }3307    // Parse MASM style pseudo prefixes.3308    if (isParsingMSInlineAsm()) {3309      if (Name.equals_insensitive("vex"))3310        ForcedOpcodePrefix = OpcodePrefix_VEX;3311      else if (Name.equals_insensitive("vex2"))3312        ForcedOpcodePrefix = OpcodePrefix_VEX2;3313      else if (Name.equals_insensitive("vex3"))3314        ForcedOpcodePrefix = OpcodePrefix_VEX3;3315      else if (Name.equals_insensitive("evex"))3316        ForcedOpcodePrefix = OpcodePrefix_EVEX;3317 3318      if (ForcedOpcodePrefix != OpcodePrefix_Default) {3319        if (getLexer().isNot(AsmToken::Identifier))3320          return Error(Parser.getTok().getLoc(), "Expected identifier");3321        // FIXME: The mnemonic won't match correctly if its not in lower case.3322        Name = Parser.getTok().getString();3323        NameLoc = Parser.getTok().getLoc();3324        Parser.Lex();3325      }3326    }3327    break;3328  }3329 3330  // Support the suffix syntax for overriding displacement size as well.3331  if (Name.consume_back(".d32")) {3332    ForcedDispEncoding = DispEncoding_Disp32;3333  } else if (Name.consume_back(".d8")) {3334    ForcedDispEncoding = DispEncoding_Disp8;3335  }3336 3337  StringRef PatchedName = Name;3338 3339  // Hack to skip "short" following Jcc.3340  if (isParsingIntelSyntax() &&3341      (PatchedName == "jmp" || PatchedName == "jc" || PatchedName == "jnc" ||3342       PatchedName == "jcxz" || PatchedName == "jecxz" ||3343       (PatchedName.starts_with("j") &&3344        ParseConditionCode(PatchedName.substr(1)) != X86::COND_INVALID))) {3345    StringRef NextTok = Parser.getTok().getString();3346    if (Parser.isParsingMasm() ? NextTok.equals_insensitive("short")3347                               : NextTok == "short") {3348      SMLoc NameEndLoc =3349          NameLoc.getFromPointer(NameLoc.getPointer() + Name.size());3350      // Eat the short keyword.3351      Parser.Lex();3352      // MS and GAS ignore the short keyword; they both determine the jmp type3353      // based on the distance of the label. (NASM does emit different code with3354      // and without "short," though.)3355      InstInfo->AsmRewrites->emplace_back(AOK_Skip, NameEndLoc,3356                                          NextTok.size() + 1);3357    }3358  }3359 3360  // FIXME: Hack to recognize setneb as setne.3361  if (PatchedName.starts_with("set") && PatchedName.ends_with("b") &&3362      PatchedName != "setzub" && PatchedName != "setzunb" &&3363      PatchedName != "setb" && PatchedName != "setnb")3364    PatchedName = PatchedName.substr(0, Name.size()-1);3365 3366  unsigned ComparisonPredicate = ~0U;3367 3368  // FIXME: Hack to recognize cmp<comparison code>{sh,ss,sd,ph,ps,pd}.3369  if ((PatchedName.starts_with("cmp") || PatchedName.starts_with("vcmp")) &&3370      (PatchedName.ends_with("ss") || PatchedName.ends_with("sd") ||3371       PatchedName.ends_with("sh") || PatchedName.ends_with("ph") ||3372       PatchedName.ends_with("bf16") || PatchedName.ends_with("ps") ||3373       PatchedName.ends_with("pd"))) {3374    bool IsVCMP = PatchedName[0] == 'v';3375    unsigned CCIdx = IsVCMP ? 4 : 3;3376    unsigned suffixLength = PatchedName.ends_with("bf16") ? 5 : 2;3377    unsigned CC = StringSwitch<unsigned>(3378      PatchedName.slice(CCIdx, PatchedName.size() - suffixLength))3379      .Case("eq",       0x00)3380      .Case("eq_oq",    0x00)3381      .Case("lt",       0x01)3382      .Case("lt_os",    0x01)3383      .Case("le",       0x02)3384      .Case("le_os",    0x02)3385      .Case("unord",    0x03)3386      .Case("unord_q",  0x03)3387      .Case("neq",      0x04)3388      .Case("neq_uq",   0x04)3389      .Case("nlt",      0x05)3390      .Case("nlt_us",   0x05)3391      .Case("nle",      0x06)3392      .Case("nle_us",   0x06)3393      .Case("ord",      0x07)3394      .Case("ord_q",    0x07)3395      /* AVX only from here */3396      .Case("eq_uq",    0x08)3397      .Case("nge",      0x09)3398      .Case("nge_us",   0x09)3399      .Case("ngt",      0x0A)3400      .Case("ngt_us",   0x0A)3401      .Case("false",    0x0B)3402      .Case("false_oq", 0x0B)3403      .Case("neq_oq",   0x0C)3404      .Case("ge",       0x0D)3405      .Case("ge_os",    0x0D)3406      .Case("gt",       0x0E)3407      .Case("gt_os",    0x0E)3408      .Case("true",     0x0F)3409      .Case("true_uq",  0x0F)3410      .Case("eq_os",    0x10)3411      .Case("lt_oq",    0x11)3412      .Case("le_oq",    0x12)3413      .Case("unord_s",  0x13)3414      .Case("neq_us",   0x14)3415      .Case("nlt_uq",   0x15)3416      .Case("nle_uq",   0x16)3417      .Case("ord_s",    0x17)3418      .Case("eq_us",    0x18)3419      .Case("nge_uq",   0x19)3420      .Case("ngt_uq",   0x1A)3421      .Case("false_os", 0x1B)3422      .Case("neq_os",   0x1C)3423      .Case("ge_oq",    0x1D)3424      .Case("gt_oq",    0x1E)3425      .Case("true_us",  0x1F)3426      .Default(~0U);3427    if (CC != ~0U && (IsVCMP || CC < 8) &&3428        (IsVCMP || PatchedName.back() != 'h')) {3429      if (PatchedName.ends_with("ss"))3430        PatchedName = IsVCMP ? "vcmpss" : "cmpss";3431      else if (PatchedName.ends_with("sd"))3432        PatchedName = IsVCMP ? "vcmpsd" : "cmpsd";3433      else if (PatchedName.ends_with("ps"))3434        PatchedName = IsVCMP ? "vcmpps" : "cmpps";3435      else if (PatchedName.ends_with("pd"))3436        PatchedName = IsVCMP ? "vcmppd" : "cmppd";3437      else if (PatchedName.ends_with("sh"))3438        PatchedName = "vcmpsh";3439      else if (PatchedName.ends_with("ph"))3440        PatchedName = "vcmpph";3441      else if (PatchedName.ends_with("bf16"))3442        PatchedName = "vcmpbf16";3443      else3444        llvm_unreachable("Unexpected suffix!");3445 3446      ComparisonPredicate = CC;3447    }3448  }3449 3450  // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}.3451  if (PatchedName.starts_with("vpcmp") &&3452      (PatchedName.back() == 'b' || PatchedName.back() == 'w' ||3453       PatchedName.back() == 'd' || PatchedName.back() == 'q')) {3454    unsigned SuffixSize = PatchedName.drop_back().back() == 'u' ? 2 : 1;3455    unsigned CC = StringSwitch<unsigned>(3456      PatchedName.slice(5, PatchedName.size() - SuffixSize))3457      .Case("eq",    0x0) // Only allowed on unsigned. Checked below.3458      .Case("lt",    0x1)3459      .Case("le",    0x2)3460      //.Case("false", 0x3) // Not a documented alias.3461      .Case("neq",   0x4)3462      .Case("nlt",   0x5)3463      .Case("nle",   0x6)3464      //.Case("true",  0x7) // Not a documented alias.3465      .Default(~0U);3466    if (CC != ~0U && (CC != 0 || SuffixSize == 2)) {3467      switch (PatchedName.back()) {3468      default: llvm_unreachable("Unexpected character!");3469      case 'b': PatchedName = SuffixSize == 2 ? "vpcmpub" : "vpcmpb"; break;3470      case 'w': PatchedName = SuffixSize == 2 ? "vpcmpuw" : "vpcmpw"; break;3471      case 'd': PatchedName = SuffixSize == 2 ? "vpcmpud" : "vpcmpd"; break;3472      case 'q': PatchedName = SuffixSize == 2 ? "vpcmpuq" : "vpcmpq"; break;3473      }3474      // Set up the immediate to push into the operands later.3475      ComparisonPredicate = CC;3476    }3477  }3478 3479  // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}.3480  if (PatchedName.starts_with("vpcom") &&3481      (PatchedName.back() == 'b' || PatchedName.back() == 'w' ||3482       PatchedName.back() == 'd' || PatchedName.back() == 'q')) {3483    unsigned SuffixSize = PatchedName.drop_back().back() == 'u' ? 2 : 1;3484    unsigned CC = StringSwitch<unsigned>(3485      PatchedName.slice(5, PatchedName.size() - SuffixSize))3486      .Case("lt",    0x0)3487      .Case("le",    0x1)3488      .Case("gt",    0x2)3489      .Case("ge",    0x3)3490      .Case("eq",    0x4)3491      .Case("neq",   0x5)3492      .Case("false", 0x6)3493      .Case("true",  0x7)3494      .Default(~0U);3495    if (CC != ~0U) {3496      switch (PatchedName.back()) {3497      default: llvm_unreachable("Unexpected character!");3498      case 'b': PatchedName = SuffixSize == 2 ? "vpcomub" : "vpcomb"; break;3499      case 'w': PatchedName = SuffixSize == 2 ? "vpcomuw" : "vpcomw"; break;3500      case 'd': PatchedName = SuffixSize == 2 ? "vpcomud" : "vpcomd"; break;3501      case 'q': PatchedName = SuffixSize == 2 ? "vpcomuq" : "vpcomq"; break;3502      }3503      // Set up the immediate to push into the operands later.3504      ComparisonPredicate = CC;3505    }3506  }3507 3508  // Determine whether this is an instruction prefix.3509  // FIXME:3510  // Enhance prefixes integrity robustness. for example, following forms3511  // are currently tolerated:3512  // repz repnz <insn>    ; GAS errors for the use of two similar prefixes3513  // lock addq %rax, %rbx ; Destination operand must be of memory type3514  // xacquire <insn>      ; xacquire must be accompanied by 'lock'3515  bool IsPrefix =3516      StringSwitch<bool>(Name)3517          .Cases({"cs", "ds", "es", "fs", "gs", "ss"}, true)3518          .Cases({"rex64", "data32", "data16", "addr32", "addr16"}, true)3519          .Cases({"xacquire", "xrelease"}, true)3520          .Cases({"acquire", "release"}, isParsingIntelSyntax())3521          .Default(false);3522 3523  auto isLockRepeatNtPrefix = [](StringRef N) {3524    return StringSwitch<bool>(N)3525        .Cases({"lock", "rep", "repe", "repz", "repne", "repnz", "notrack"},3526               true)3527        .Default(false);3528  };3529 3530  bool CurlyAsEndOfStatement = false;3531 3532  unsigned Flags = X86::IP_NO_PREFIX;3533  while (isLockRepeatNtPrefix(Name.lower())) {3534    unsigned Prefix =3535        StringSwitch<unsigned>(Name)3536            .Case("lock", X86::IP_HAS_LOCK)3537            .Cases({"rep", "repe", "repz"}, X86::IP_HAS_REPEAT)3538            .Cases({"repne", "repnz"}, X86::IP_HAS_REPEAT_NE)3539            .Case("notrack", X86::IP_HAS_NOTRACK)3540            .Default(X86::IP_NO_PREFIX); // Invalid prefix (impossible)3541    Flags |= Prefix;3542    if (getLexer().is(AsmToken::EndOfStatement)) {3543      // We don't have real instr with the given prefix3544      //  let's use the prefix as the instr.3545      // TODO: there could be several prefixes one after another3546      Flags = X86::IP_NO_PREFIX;3547      break;3548    }3549    // FIXME: The mnemonic won't match correctly if its not in lower case.3550    Name = Parser.getTok().getString();3551    Parser.Lex(); // eat the prefix3552    // Hack: we could have something like "rep # some comment" or3553    //    "lock; cmpxchg16b $1" or "lock\0A\09incl" or "lock/incl"3554    while (Name.starts_with(";") || Name.starts_with("\n") ||3555           Name.starts_with("#") || Name.starts_with("\t") ||3556           Name.starts_with("/")) {3557      // FIXME: The mnemonic won't match correctly if its not in lower case.3558      Name = Parser.getTok().getString();3559      Parser.Lex(); // go to next prefix or instr3560    }3561  }3562 3563  if (Flags)3564    PatchedName = Name;3565 3566  // Hacks to handle 'data16' and 'data32'3567  if (PatchedName == "data16" && is16BitMode()) {3568    return Error(NameLoc, "redundant data16 prefix");3569  }3570  if (PatchedName == "data32") {3571    if (is32BitMode())3572      return Error(NameLoc, "redundant data32 prefix");3573    if (is64BitMode())3574      return Error(NameLoc, "'data32' is not supported in 64-bit mode");3575    // Hack to 'data16' for the table lookup.3576    PatchedName = "data16";3577 3578    if (getLexer().isNot(AsmToken::EndOfStatement)) {3579      StringRef Next = Parser.getTok().getString();3580      getLexer().Lex();3581      // data32 effectively changes the instruction suffix.3582      // TODO Generalize.3583      if (Next == "callw")3584        Next = "calll";3585      if (Next == "ljmpw")3586        Next = "ljmpl";3587 3588      Name = Next;3589      PatchedName = Name;3590      ForcedDataPrefix = X86::Is32Bit;3591      IsPrefix = false;3592    }3593  }3594 3595  Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));3596 3597  // Push the immediate if we extracted one from the mnemonic.3598  if (ComparisonPredicate != ~0U && !isParsingIntelSyntax()) {3599    const MCExpr *ImmOp = MCConstantExpr::create(ComparisonPredicate,3600                                                 getParser().getContext());3601    Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));3602  }3603 3604  // Parse condtional flags after mnemonic.3605  if ((Name.starts_with("ccmp") || Name.starts_with("ctest")) &&3606      parseCFlagsOp(Operands))3607    return true;3608 3609  // This does the actual operand parsing.  Don't parse any more if we have a3610  // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we3611  // just want to parse the "lock" as the first instruction and the "incl" as3612  // the next one.3613  if (getLexer().isNot(AsmToken::EndOfStatement) && !IsPrefix) {3614    // Parse '*' modifier.3615    if (getLexer().is(AsmToken::Star))3616      Operands.push_back(X86Operand::CreateToken("*", consumeToken()));3617 3618    // Read the operands.3619    while (true) {3620      if (parseOperand(Operands, Name))3621        return true;3622      if (HandleAVX512Operand(Operands))3623        return true;3624 3625      // check for comma and eat it3626      if (getLexer().is(AsmToken::Comma))3627        Parser.Lex();3628      else3629        break;3630     }3631 3632    // In MS inline asm curly braces mark the beginning/end of a block,3633    // therefore they should be interepreted as end of statement3634    CurlyAsEndOfStatement =3635        isParsingIntelSyntax() && isParsingMSInlineAsm() &&3636        (getLexer().is(AsmToken::LCurly) || getLexer().is(AsmToken::RCurly));3637    if (getLexer().isNot(AsmToken::EndOfStatement) && !CurlyAsEndOfStatement)3638      return TokError("unexpected token in argument list");3639  }3640 3641  // Push the immediate if we extracted one from the mnemonic.3642  if (ComparisonPredicate != ~0U && isParsingIntelSyntax()) {3643    const MCExpr *ImmOp = MCConstantExpr::create(ComparisonPredicate,3644                                                 getParser().getContext());3645    Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));3646  }3647 3648  // Consume the EndOfStatement or the prefix separator Slash3649  if (getLexer().is(AsmToken::EndOfStatement) ||3650      (IsPrefix && getLexer().is(AsmToken::Slash)))3651    Parser.Lex();3652  else if (CurlyAsEndOfStatement)3653    // Add an actual EndOfStatement before the curly brace3654    Info.AsmRewrites->emplace_back(AOK_EndOfStatement,3655                                   getLexer().getTok().getLoc(), 0);3656 3657  // This is for gas compatibility and cannot be done in td.3658  // Adding "p" for some floating point with no argument.3659  // For example: fsub --> fsubp3660  bool IsFp =3661    Name == "fsub" || Name == "fdiv" || Name == "fsubr" || Name == "fdivr";3662  if (IsFp && Operands.size() == 1) {3663    const char *Repl = StringSwitch<const char *>(Name)3664      .Case("fsub", "fsubp")3665      .Case("fdiv", "fdivp")3666      .Case("fsubr", "fsubrp")3667      .Case("fdivr", "fdivrp");3668    static_cast<X86Operand &>(*Operands[0]).setTokenValue(Repl);3669  }3670 3671  if ((Name == "mov" || Name == "movw" || Name == "movl") &&3672      (Operands.size() == 3)) {3673    X86Operand &Op1 = (X86Operand &)*Operands[1];3674    X86Operand &Op2 = (X86Operand &)*Operands[2];3675    SMLoc Loc = Op1.getEndLoc();3676    // Moving a 32 or 16 bit value into a segment register has the same3677    // behavior. Modify such instructions to always take shorter form.3678    if (Op1.isReg() && Op2.isReg() &&3679        X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(3680            Op2.getReg()) &&3681        (X86MCRegisterClasses[X86::GR16RegClassID].contains(Op1.getReg()) ||3682         X86MCRegisterClasses[X86::GR32RegClassID].contains(Op1.getReg()))) {3683      // Change instruction name to match new instruction.3684      if (Name != "mov" && Name[3] == (is16BitMode() ? 'l' : 'w')) {3685        Name = is16BitMode() ? "movw" : "movl";3686        Operands[0] = X86Operand::CreateToken(Name, NameLoc);3687      }3688      // Select the correct equivalent 16-/32-bit source register.3689      MCRegister Reg =3690          getX86SubSuperRegister(Op1.getReg(), is16BitMode() ? 16 : 32);3691      Operands[1] = X86Operand::CreateReg(Reg, Loc, Loc);3692    }3693  }3694 3695  // This is a terrible hack to handle "out[s]?[bwl]? %al, (%dx)" ->3696  // "outb %al, %dx".  Out doesn't take a memory form, but this is a widely3697  // documented form in various unofficial manuals, so a lot of code uses it.3698  if ((Name == "outb" || Name == "outsb" || Name == "outw" || Name == "outsw" ||3699       Name == "outl" || Name == "outsl" || Name == "out" || Name == "outs") &&3700      Operands.size() == 3) {3701    X86Operand &Op = (X86Operand &)*Operands.back();3702    if (Op.isDXReg())3703      Operands.back() = X86Operand::CreateReg(X86::DX, Op.getStartLoc(),3704                                              Op.getEndLoc());3705  }3706  // Same hack for "in[s]?[bwl]? (%dx), %al" -> "inb %dx, %al".3707  if ((Name == "inb" || Name == "insb" || Name == "inw" || Name == "insw" ||3708       Name == "inl" || Name == "insl" || Name == "in" || Name == "ins") &&3709      Operands.size() == 3) {3710    X86Operand &Op = (X86Operand &)*Operands[1];3711    if (Op.isDXReg())3712      Operands[1] = X86Operand::CreateReg(X86::DX, Op.getStartLoc(),3713                                          Op.getEndLoc());3714  }3715 3716  SmallVector<std::unique_ptr<MCParsedAsmOperand>, 2> TmpOperands;3717  bool HadVerifyError = false;3718 3719  // Append default arguments to "ins[bwld]"3720  if (Name.starts_with("ins") &&3721      (Operands.size() == 1 || Operands.size() == 3) &&3722      (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd" ||3723       Name == "ins")) {3724 3725    AddDefaultSrcDestOperands(TmpOperands,3726                              X86Operand::CreateReg(X86::DX, NameLoc, NameLoc),3727                              DefaultMemDIOperand(NameLoc));3728    HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);3729  }3730 3731  // Append default arguments to "outs[bwld]"3732  if (Name.starts_with("outs") &&3733      (Operands.size() == 1 || Operands.size() == 3) &&3734      (Name == "outsb" || Name == "outsw" || Name == "outsl" ||3735       Name == "outsd" || Name == "outs")) {3736    AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),3737                              X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));3738    HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);3739  }3740 3741  // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate3742  // values of $SIREG according to the mode. It would be nice if this3743  // could be achieved with InstAlias in the tables.3744  if (Name.starts_with("lods") &&3745      (Operands.size() == 1 || Operands.size() == 2) &&3746      (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||3747       Name == "lodsl" || Name == "lodsd" || Name == "lodsq")) {3748    TmpOperands.push_back(DefaultMemSIOperand(NameLoc));3749    HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);3750  }3751 3752  // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate3753  // values of $DIREG according to the mode. It would be nice if this3754  // could be achieved with InstAlias in the tables.3755  if (Name.starts_with("stos") &&3756      (Operands.size() == 1 || Operands.size() == 2) &&3757      (Name == "stos" || Name == "stosb" || Name == "stosw" ||3758       Name == "stosl" || Name == "stosd" || Name == "stosq")) {3759    TmpOperands.push_back(DefaultMemDIOperand(NameLoc));3760    HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);3761  }3762 3763  // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate3764  // values of $DIREG according to the mode. It would be nice if this3765  // could be achieved with InstAlias in the tables.3766  if (Name.starts_with("scas") &&3767      (Operands.size() == 1 || Operands.size() == 2) &&3768      (Name == "scas" || Name == "scasb" || Name == "scasw" ||3769       Name == "scasl" || Name == "scasd" || Name == "scasq")) {3770    TmpOperands.push_back(DefaultMemDIOperand(NameLoc));3771    HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);3772  }3773 3774  // Add default SI and DI operands to "cmps[bwlq]".3775  if (Name.starts_with("cmps") &&3776      (Operands.size() == 1 || Operands.size() == 3) &&3777      (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||3778       Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {3779    AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),3780                              DefaultMemSIOperand(NameLoc));3781    HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);3782  }3783 3784  // Add default SI and DI operands to "movs[bwlq]".3785  if (((Name.starts_with("movs") &&3786        (Name == "movs" || Name == "movsb" || Name == "movsw" ||3787         Name == "movsl" || Name == "movsd" || Name == "movsq")) ||3788       (Name.starts_with("smov") &&3789        (Name == "smov" || Name == "smovb" || Name == "smovw" ||3790         Name == "smovl" || Name == "smovd" || Name == "smovq"))) &&3791      (Operands.size() == 1 || Operands.size() == 3)) {3792    if (Name == "movsd" && Operands.size() == 1 && !isParsingIntelSyntax())3793      Operands.back() = X86Operand::CreateToken("movsl", NameLoc);3794    AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),3795                              DefaultMemDIOperand(NameLoc));3796    HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);3797  }3798 3799  // Check if we encountered an error for one the string insturctions3800  if (HadVerifyError) {3801    return HadVerifyError;3802  }3803 3804  // Transforms "xlat mem8" into "xlatb"3805  if ((Name == "xlat" || Name == "xlatb") && Operands.size() == 2) {3806    X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);3807    if (Op1.isMem8()) {3808      Warning(Op1.getStartLoc(), "memory operand is only for determining the "3809                                 "size, (R|E)BX will be used for the location");3810      Operands.pop_back();3811      static_cast<X86Operand &>(*Operands[0]).setTokenValue("xlatb");3812    }3813  }3814 3815  if (Flags)3816    Operands.push_back(X86Operand::CreatePrefix(Flags, NameLoc, NameLoc));3817  return false;3818}3819 3820static bool convertSSEToAVX(MCInst &Inst) {3821  ArrayRef<X86TableEntry> Table{X86SSE2AVXTable};3822  unsigned Opcode = Inst.getOpcode();3823  const auto I = llvm::lower_bound(Table, Opcode);3824  if (I == Table.end() || I->OldOpc != Opcode)3825    return false;3826 3827  Inst.setOpcode(I->NewOpc);3828  // AVX variant of BLENDVPD/BLENDVPS/PBLENDVB instructions has more3829  // operand compare to SSE variant, which is added below3830  if (X86::isBLENDVPD(Opcode) || X86::isBLENDVPS(Opcode) ||3831      X86::isPBLENDVB(Opcode))3832    Inst.addOperand(Inst.getOperand(2));3833 3834  return true;3835}3836 3837bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {3838  if (MCOptions.X86Sse2Avx && convertSSEToAVX(Inst))3839    return true;3840 3841  if (ForcedOpcodePrefix != OpcodePrefix_VEX3 &&3842      X86::optimizeInstFromVEX3ToVEX2(Inst, MII.get(Inst.getOpcode())))3843    return true;3844 3845  if (X86::optimizeShiftRotateWithImmediateOne(Inst))3846    return true;3847 3848  auto replaceWithCCMPCTEST = [&](unsigned Opcode) -> bool {3849    if (ForcedOpcodePrefix == OpcodePrefix_EVEX) {3850      Inst.setFlags(~(X86::IP_USE_EVEX)&Inst.getFlags());3851      Inst.setOpcode(Opcode);3852      Inst.addOperand(MCOperand::createImm(0));3853      Inst.addOperand(MCOperand::createImm(10));3854      return true;3855    }3856    return false;3857  };3858 3859  switch (Inst.getOpcode()) {3860  default: return false;3861  case X86::JMP_1:3862    // {disp32} forces a larger displacement as if the instruction was relaxed.3863    // NOTE: 16-bit mode uses 16-bit displacement even though it says {disp32}.3864    // This matches GNU assembler.3865    if (ForcedDispEncoding == DispEncoding_Disp32) {3866      Inst.setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);3867      return true;3868    }3869 3870    return false;3871  case X86::JCC_1:3872    // {disp32} forces a larger displacement as if the instruction was relaxed.3873    // NOTE: 16-bit mode uses 16-bit displacement even though it says {disp32}.3874    // This matches GNU assembler.3875    if (ForcedDispEncoding == DispEncoding_Disp32) {3876      Inst.setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);3877      return true;3878    }3879 3880    return false;3881  case X86::INT: {3882    // Transforms "int $3" into "int3" as a size optimization.3883    // We can't write this as an InstAlias.3884    if (!Inst.getOperand(0).isImm() || Inst.getOperand(0).getImm() != 3)3885      return false;3886    Inst.clear();3887    Inst.setOpcode(X86::INT3);3888    return true;3889  }3890  // `{evex} cmp <>, <>` is alias of `ccmpt {dfv=} <>, <>`, and3891  // `{evex} test <>, <>` is alias of `ctest {dfv=} <>, <>`3892#define FROM_TO(FROM, TO)                                                      \3893  case X86::FROM:                                                              \3894    return replaceWithCCMPCTEST(X86::TO);3895    FROM_TO(CMP64rr, CCMP64rr)3896    FROM_TO(CMP64mi32, CCMP64mi32)3897    FROM_TO(CMP64mi8, CCMP64mi8)3898    FROM_TO(CMP64mr, CCMP64mr)3899    FROM_TO(CMP64ri32, CCMP64ri32)3900    FROM_TO(CMP64ri8, CCMP64ri8)3901    FROM_TO(CMP64rm, CCMP64rm)3902 3903    FROM_TO(CMP32rr, CCMP32rr)3904    FROM_TO(CMP32mi, CCMP32mi)3905    FROM_TO(CMP32mi8, CCMP32mi8)3906    FROM_TO(CMP32mr, CCMP32mr)3907    FROM_TO(CMP32ri, CCMP32ri)3908    FROM_TO(CMP32ri8, CCMP32ri8)3909    FROM_TO(CMP32rm, CCMP32rm)3910 3911    FROM_TO(CMP16rr, CCMP16rr)3912    FROM_TO(CMP16mi, CCMP16mi)3913    FROM_TO(CMP16mi8, CCMP16mi8)3914    FROM_TO(CMP16mr, CCMP16mr)3915    FROM_TO(CMP16ri, CCMP16ri)3916    FROM_TO(CMP16ri8, CCMP16ri8)3917    FROM_TO(CMP16rm, CCMP16rm)3918 3919    FROM_TO(CMP8rr, CCMP8rr)3920    FROM_TO(CMP8mi, CCMP8mi)3921    FROM_TO(CMP8mr, CCMP8mr)3922    FROM_TO(CMP8ri, CCMP8ri)3923    FROM_TO(CMP8rm, CCMP8rm)3924 3925    FROM_TO(TEST64rr, CTEST64rr)3926    FROM_TO(TEST64mi32, CTEST64mi32)3927    FROM_TO(TEST64mr, CTEST64mr)3928    FROM_TO(TEST64ri32, CTEST64ri32)3929 3930    FROM_TO(TEST32rr, CTEST32rr)3931    FROM_TO(TEST32mi, CTEST32mi)3932    FROM_TO(TEST32mr, CTEST32mr)3933    FROM_TO(TEST32ri, CTEST32ri)3934 3935    FROM_TO(TEST16rr, CTEST16rr)3936    FROM_TO(TEST16mi, CTEST16mi)3937    FROM_TO(TEST16mr, CTEST16mr)3938    FROM_TO(TEST16ri, CTEST16ri)3939 3940    FROM_TO(TEST8rr, CTEST8rr)3941    FROM_TO(TEST8mi, CTEST8mi)3942    FROM_TO(TEST8mr, CTEST8mr)3943    FROM_TO(TEST8ri, CTEST8ri)3944#undef FROM_TO3945  }3946}3947 3948bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {3949  using namespace X86;3950  const MCRegisterInfo *MRI = getContext().getRegisterInfo();3951  unsigned Opcode = Inst.getOpcode();3952  uint64_t TSFlags = MII.get(Opcode).TSFlags;3953  if (isVFCMADDCPH(Opcode) || isVFCMADDCSH(Opcode) || isVFMADDCPH(Opcode) ||3954      isVFMADDCSH(Opcode)) {3955    MCRegister Dest = Inst.getOperand(0).getReg();3956    for (unsigned i = 2; i < Inst.getNumOperands(); i++)3957      if (Inst.getOperand(i).isReg() && Dest == Inst.getOperand(i).getReg())3958        return Warning(Ops[0]->getStartLoc(), "Destination register should be "3959                                              "distinct from source registers");3960  } else if (isVFCMULCPH(Opcode) || isVFCMULCSH(Opcode) || isVFMULCPH(Opcode) ||3961             isVFMULCSH(Opcode)) {3962    MCRegister Dest = Inst.getOperand(0).getReg();3963    // The mask variants have different operand list. Scan from the third3964    // operand to avoid emitting incorrect warning.3965    //    VFMULCPHZrr   Dest, Src1, Src23966    //    VFMULCPHZrrk  Dest, Dest, Mask, Src1, Src23967    //    VFMULCPHZrrkz Dest, Mask, Src1, Src23968    for (unsigned i = ((TSFlags & X86II::EVEX_K) ? 2 : 1);3969         i < Inst.getNumOperands(); i++)3970      if (Inst.getOperand(i).isReg() && Dest == Inst.getOperand(i).getReg())3971        return Warning(Ops[0]->getStartLoc(), "Destination register should be "3972                                              "distinct from source registers");3973  } else if (isV4FMADDPS(Opcode) || isV4FMADDSS(Opcode) ||3974             isV4FNMADDPS(Opcode) || isV4FNMADDSS(Opcode) ||3975             isVP4DPWSSDS(Opcode) || isVP4DPWSSD(Opcode)) {3976    MCRegister Src2 =3977        Inst.getOperand(Inst.getNumOperands() - X86::AddrNumOperands - 1)3978            .getReg();3979    unsigned Src2Enc = MRI->getEncodingValue(Src2);3980    if (Src2Enc % 4 != 0) {3981      StringRef RegName = X86IntelInstPrinter::getRegisterName(Src2);3982      unsigned GroupStart = (Src2Enc / 4) * 4;3983      unsigned GroupEnd = GroupStart + 3;3984      return Warning(Ops[0]->getStartLoc(),3985                     "source register '" + RegName + "' implicitly denotes '" +3986                     RegName.take_front(3) + Twine(GroupStart) + "' to '" +3987                     RegName.take_front(3) + Twine(GroupEnd) +3988                     "' source group");3989    }3990  } else if (isVGATHERDPD(Opcode) || isVGATHERDPS(Opcode) ||3991             isVGATHERQPD(Opcode) || isVGATHERQPS(Opcode) ||3992             isVPGATHERDD(Opcode) || isVPGATHERDQ(Opcode) ||3993             isVPGATHERQD(Opcode) || isVPGATHERQQ(Opcode)) {3994    bool HasEVEX = (TSFlags & X86II::EncodingMask) == X86II::EVEX;3995    if (HasEVEX) {3996      unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg());3997      unsigned Index = MRI->getEncodingValue(3998          Inst.getOperand(4 + X86::AddrIndexReg).getReg());3999      if (Dest == Index)4000        return Warning(Ops[0]->getStartLoc(), "index and destination registers "4001                                              "should be distinct");4002    } else {4003      unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg());4004      unsigned Mask = MRI->getEncodingValue(Inst.getOperand(1).getReg());4005      unsigned Index = MRI->getEncodingValue(4006          Inst.getOperand(3 + X86::AddrIndexReg).getReg());4007      if (Dest == Mask || Dest == Index || Mask == Index)4008        return Warning(Ops[0]->getStartLoc(), "mask, index, and destination "4009                                              "registers should be distinct");4010    }4011  } else if (isTCMMIMFP16PS(Opcode) || isTCMMRLFP16PS(Opcode) ||4012             isTDPBF16PS(Opcode) || isTDPFP16PS(Opcode) || isTDPBSSD(Opcode) ||4013             isTDPBSUD(Opcode) || isTDPBUSD(Opcode) || isTDPBUUD(Opcode)) {4014    MCRegister SrcDest = Inst.getOperand(0).getReg();4015    MCRegister Src1 = Inst.getOperand(2).getReg();4016    MCRegister Src2 = Inst.getOperand(3).getReg();4017    if (SrcDest == Src1 || SrcDest == Src2 || Src1 == Src2)4018      return Error(Ops[0]->getStartLoc(), "all tmm registers must be distinct");4019  }4020 4021  // High 8-bit regs (AH/BH/CH/DH) are incompatible with encodings that imply4022  // extended prefixes:4023  //  * Legacy path that would emit a REX (e.g. uses r8..r15 or sil/dil/bpl/spl)4024  //  * EVEX4025  //  * REX24026  // VEX/XOP don't use REX; they are excluded from the legacy check.4027  const unsigned Enc = TSFlags & X86II::EncodingMask;4028  if (Enc != X86II::VEX && Enc != X86II::XOP) {4029    MCRegister HReg;4030    bool UsesRex = TSFlags & X86II::REX_W;4031    unsigned NumOps = Inst.getNumOperands();4032    for (unsigned i = 0; i != NumOps; ++i) {4033      const MCOperand &MO = Inst.getOperand(i);4034      if (!MO.isReg())4035        continue;4036      MCRegister Reg = MO.getReg();4037      if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH)4038        HReg = Reg;4039      if (X86II::isX86_64NonExtLowByteReg(Reg) ||4040          X86II::isX86_64ExtendedReg(Reg))4041        UsesRex = true;4042    }4043 4044    if (HReg &&4045        (Enc == X86II::EVEX || ForcedOpcodePrefix == OpcodePrefix_REX2 ||4046         ForcedOpcodePrefix == OpcodePrefix_REX || UsesRex)) {4047      StringRef RegName = X86IntelInstPrinter::getRegisterName(HReg);4048      return Error(Ops[0]->getStartLoc(),4049                   "can't encode '" + RegName.str() +4050                       "' in an instruction requiring EVEX/REX2/REX prefix");4051    }4052  }4053 4054  if ((Opcode == X86::PREFETCHIT0 || Opcode == X86::PREFETCHIT1)) {4055    const MCOperand &MO = Inst.getOperand(X86::AddrBaseReg);4056    if (!MO.isReg() || MO.getReg() != X86::RIP)4057      return Warning(4058          Ops[0]->getStartLoc(),4059          Twine((Inst.getOpcode() == X86::PREFETCHIT0 ? "'prefetchit0'"4060                                                      : "'prefetchit1'")) +4061              " only supports RIP-relative address");4062  }4063  return false;4064}4065 4066void X86AsmParser::emitWarningForSpecialLVIInstruction(SMLoc Loc) {4067  Warning(Loc, "Instruction may be vulnerable to LVI and "4068               "requires manual mitigation");4069  Note(SMLoc(), "See https://software.intel.com/"4070                "security-software-guidance/insights/"4071                "deep-dive-load-value-injection#specialinstructions"4072                " for more information");4073}4074 4075/// RET instructions and also instructions that indirect calls/jumps from memory4076/// combine a load and a branch within a single instruction. To mitigate these4077/// instructions against LVI, they must be decomposed into separate load and4078/// branch instructions, with an LFENCE in between. For more details, see:4079/// - X86LoadValueInjectionRetHardening.cpp4080/// - X86LoadValueInjectionIndirectThunks.cpp4081/// - https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection4082///4083/// Returns `true` if a mitigation was applied or warning was emitted.4084void X86AsmParser::applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out) {4085  // Information on control-flow instructions that require manual mitigation can4086  // be found here:4087  // https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection#specialinstructions4088  switch (Inst.getOpcode()) {4089  case X86::RET16:4090  case X86::RET32:4091  case X86::RET64:4092  case X86::RETI16:4093  case X86::RETI32:4094  case X86::RETI64: {4095    MCInst ShlInst, FenceInst;4096    bool Parse32 = is32BitMode() || Code16GCC;4097    MCRegister Basereg =4098        is64BitMode() ? X86::RSP : (Parse32 ? X86::ESP : X86::SP);4099    const MCExpr *Disp = MCConstantExpr::create(0, getContext());4100    auto ShlMemOp = X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,4101                                          /*BaseReg=*/Basereg, /*IndexReg=*/0,4102                                          /*Scale=*/1, SMLoc{}, SMLoc{}, 0);4103    ShlInst.setOpcode(X86::SHL64mi);4104    ShlMemOp->addMemOperands(ShlInst, 5);4105    ShlInst.addOperand(MCOperand::createImm(0));4106    FenceInst.setOpcode(X86::LFENCE);4107    Out.emitInstruction(ShlInst, getSTI());4108    Out.emitInstruction(FenceInst, getSTI());4109    return;4110  }4111  case X86::JMP16m:4112  case X86::JMP32m:4113  case X86::JMP64m:4114  case X86::CALL16m:4115  case X86::CALL32m:4116  case X86::CALL64m:4117    emitWarningForSpecialLVIInstruction(Inst.getLoc());4118    return;4119  }4120}4121 4122/// To mitigate LVI, every instruction that performs a load can be followed by4123/// an LFENCE instruction to squash any potential mis-speculation. There are4124/// some instructions that require additional considerations, and may requre4125/// manual mitigation. For more details, see:4126/// https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection4127///4128/// Returns `true` if a mitigation was applied or warning was emitted.4129void X86AsmParser::applyLVILoadHardeningMitigation(MCInst &Inst,4130                                                   MCStreamer &Out) {4131  auto Opcode = Inst.getOpcode();4132  auto Flags = Inst.getFlags();4133  if ((Flags & X86::IP_HAS_REPEAT) || (Flags & X86::IP_HAS_REPEAT_NE)) {4134    // Information on REP string instructions that require manual mitigation can4135    // be found here:4136    // https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection#specialinstructions4137    switch (Opcode) {4138    case X86::CMPSB:4139    case X86::CMPSW:4140    case X86::CMPSL:4141    case X86::CMPSQ:4142    case X86::SCASB:4143    case X86::SCASW:4144    case X86::SCASL:4145    case X86::SCASQ:4146      emitWarningForSpecialLVIInstruction(Inst.getLoc());4147      return;4148    }4149  } else if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) {4150    // If a REP instruction is found on its own line, it may or may not be4151    // followed by a vulnerable instruction. Emit a warning just in case.4152    emitWarningForSpecialLVIInstruction(Inst.getLoc());4153    return;4154  }4155 4156  const MCInstrDesc &MCID = MII.get(Inst.getOpcode());4157 4158  // Can't mitigate after terminators or calls. A control flow change may have4159  // already occurred.4160  if (MCID.isTerminator() || MCID.isCall())4161    return;4162 4163  // LFENCE has the mayLoad property, don't double fence.4164  if (MCID.mayLoad() && Inst.getOpcode() != X86::LFENCE) {4165    MCInst FenceInst;4166    FenceInst.setOpcode(X86::LFENCE);4167    Out.emitInstruction(FenceInst, getSTI());4168  }4169}4170 4171void X86AsmParser::emitInstruction(MCInst &Inst, OperandVector &Operands,4172                                   MCStreamer &Out) {4173  if (LVIInlineAsmHardening &&4174      getSTI().hasFeature(X86::FeatureLVIControlFlowIntegrity))4175    applyLVICFIMitigation(Inst, Out);4176 4177  Out.emitInstruction(Inst, getSTI());4178 4179  if (LVIInlineAsmHardening &&4180      getSTI().hasFeature(X86::FeatureLVILoadHardening))4181    applyLVILoadHardeningMitigation(Inst, Out);4182}4183 4184static unsigned getPrefixes(OperandVector &Operands) {4185  unsigned Result = 0;4186  X86Operand &Prefix = static_cast<X86Operand &>(*Operands.back());4187  if (Prefix.isPrefix()) {4188    Result = Prefix.getPrefix();4189    Operands.pop_back();4190  }4191  return Result;4192}4193 4194bool X86AsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,4195                                           OperandVector &Operands,4196                                           MCStreamer &Out, uint64_t &ErrorInfo,4197                                           bool MatchingInlineAsm) {4198  assert(!Operands.empty() && "Unexpect empty operand list!");4199  assert((*Operands[0]).isToken() && "Leading operand should always be a mnemonic!");4200 4201  // First, handle aliases that expand to multiple instructions.4202  MatchFPUWaitAlias(IDLoc, static_cast<X86Operand &>(*Operands[0]), Operands,4203                    Out, MatchingInlineAsm);4204  unsigned Prefixes = getPrefixes(Operands);4205 4206  MCInst Inst;4207 4208  // If REX/REX2/VEX/EVEX encoding is forced, we need to pass the USE_* flag to4209  // the encoder and printer.4210  if (ForcedOpcodePrefix == OpcodePrefix_REX)4211    Prefixes |= X86::IP_USE_REX;4212  else if (ForcedOpcodePrefix == OpcodePrefix_REX2)4213    Prefixes |= X86::IP_USE_REX2;4214  else if (ForcedOpcodePrefix == OpcodePrefix_VEX)4215    Prefixes |= X86::IP_USE_VEX;4216  else if (ForcedOpcodePrefix == OpcodePrefix_VEX2)4217    Prefixes |= X86::IP_USE_VEX2;4218  else if (ForcedOpcodePrefix == OpcodePrefix_VEX3)4219    Prefixes |= X86::IP_USE_VEX3;4220  else if (ForcedOpcodePrefix == OpcodePrefix_EVEX)4221    Prefixes |= X86::IP_USE_EVEX;4222 4223  // Set encoded flags for {disp8} and {disp32}.4224  if (ForcedDispEncoding == DispEncoding_Disp8)4225    Prefixes |= X86::IP_USE_DISP8;4226  else if (ForcedDispEncoding == DispEncoding_Disp32)4227    Prefixes |= X86::IP_USE_DISP32;4228 4229  if (Prefixes)4230    Inst.setFlags(Prefixes);4231 4232  return isParsingIntelSyntax()4233             ? matchAndEmitIntelInstruction(IDLoc, Opcode, Inst, Operands, Out,4234                                            ErrorInfo, MatchingInlineAsm)4235             : matchAndEmitATTInstruction(IDLoc, Opcode, Inst, Operands, Out,4236                                          ErrorInfo, MatchingInlineAsm);4237}4238 4239void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,4240                                     OperandVector &Operands, MCStreamer &Out,4241                                     bool MatchingInlineAsm) {4242  // FIXME: This should be replaced with a real .td file alias mechanism.4243  // Also, MatchInstructionImpl should actually *do* the EmitInstruction4244  // call.4245  const char *Repl = StringSwitch<const char *>(Op.getToken())4246                         .Case("finit", "fninit")4247                         .Case("fsave", "fnsave")4248                         .Case("fstcw", "fnstcw")4249                         .Case("fstcww", "fnstcw")4250                         .Case("fstenv", "fnstenv")4251                         .Case("fstsw", "fnstsw")4252                         .Case("fstsww", "fnstsw")4253                         .Case("fclex", "fnclex")4254                         .Default(nullptr);4255  if (Repl) {4256    MCInst Inst;4257    Inst.setOpcode(X86::WAIT);4258    Inst.setLoc(IDLoc);4259    if (!MatchingInlineAsm)4260      emitInstruction(Inst, Operands, Out);4261    Operands[0] = X86Operand::CreateToken(Repl, IDLoc);4262  }4263}4264 4265bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc,4266                                       const FeatureBitset &MissingFeatures,4267                                       bool MatchingInlineAsm) {4268  assert(MissingFeatures.any() && "Unknown missing feature!");4269  SmallString<126> Msg;4270  raw_svector_ostream OS(Msg);4271  OS << "instruction requires:";4272  for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {4273    if (MissingFeatures[i])4274      OS << ' ' << getSubtargetFeatureName(i);4275  }4276  return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);4277}4278 4279unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {4280  unsigned Opc = Inst.getOpcode();4281  const MCInstrDesc &MCID = MII.get(Opc);4282  uint64_t TSFlags = MCID.TSFlags;4283 4284  if (UseApxExtendedReg && !X86II::canUseApxExtendedReg(MCID))4285    return Match_Unsupported;4286  if (ForcedNoFlag == !(TSFlags & X86II::EVEX_NF) && !X86::isCFCMOVCC(Opc))4287    return Match_Unsupported;4288 4289  switch (ForcedOpcodePrefix) {4290  case OpcodePrefix_Default:4291    break;4292  case OpcodePrefix_REX:4293  case OpcodePrefix_REX2:4294    if (TSFlags & X86II::EncodingMask)4295      return Match_Unsupported;4296    break;4297  case OpcodePrefix_VEX:4298  case OpcodePrefix_VEX2:4299  case OpcodePrefix_VEX3:4300    if ((TSFlags & X86II::EncodingMask) != X86II::VEX)4301      return Match_Unsupported;4302    break;4303  case OpcodePrefix_EVEX:4304    if (is64BitMode() && (TSFlags & X86II::EncodingMask) != X86II::EVEX &&4305        !X86::isCMP(Opc) && !X86::isTEST(Opc))4306      return Match_Unsupported;4307    if (!is64BitMode() && (TSFlags & X86II::EncodingMask) != X86II::EVEX)4308      return Match_Unsupported;4309    break;4310  }4311 4312  if ((TSFlags & X86II::ExplicitOpPrefixMask) == X86II::ExplicitVEXPrefix &&4313      (ForcedOpcodePrefix != OpcodePrefix_VEX &&4314       ForcedOpcodePrefix != OpcodePrefix_VEX2 &&4315       ForcedOpcodePrefix != OpcodePrefix_VEX3))4316    return Match_Unsupported;4317 4318  return Match_Success;4319}4320 4321bool X86AsmParser::matchAndEmitATTInstruction(4322    SMLoc IDLoc, unsigned &Opcode, MCInst &Inst, OperandVector &Operands,4323    MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm) {4324  X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);4325  SMRange EmptyRange;4326  // In 16-bit mode, if data32 is specified, temporarily switch to 32-bit mode4327  // when matching the instruction.4328  if (ForcedDataPrefix == X86::Is32Bit)4329    SwitchMode(X86::Is32Bit);4330  // First, try a direct match.4331  FeatureBitset MissingFeatures;4332  unsigned OriginalError = MatchInstruction(Operands, Inst, ErrorInfo,4333                                            MissingFeatures, MatchingInlineAsm,4334                                            isParsingIntelSyntax());4335  if (ForcedDataPrefix == X86::Is32Bit) {4336    SwitchMode(X86::Is16Bit);4337    ForcedDataPrefix = 0;4338  }4339  switch (OriginalError) {4340  default: llvm_unreachable("Unexpected match result!");4341  case Match_Success:4342    if (!MatchingInlineAsm && validateInstruction(Inst, Operands))4343      return true;4344    // Some instructions need post-processing to, for example, tweak which4345    // encoding is selected. Loop on it while changes happen so the4346    // individual transformations can chain off each other.4347    if (!MatchingInlineAsm)4348      while (processInstruction(Inst, Operands))4349        ;4350 4351    Inst.setLoc(IDLoc);4352    if (!MatchingInlineAsm)4353      emitInstruction(Inst, Operands, Out);4354    Opcode = Inst.getOpcode();4355    return false;4356  case Match_InvalidImmUnsignedi4: {4357    SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();4358    if (ErrorLoc == SMLoc())4359      ErrorLoc = IDLoc;4360    return Error(ErrorLoc, "immediate must be an integer in range [0, 15]",4361                 EmptyRange, MatchingInlineAsm);4362  }4363  case Match_MissingFeature:4364    return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);4365  case Match_InvalidOperand:4366  case Match_MnemonicFail:4367  case Match_Unsupported:4368    break;4369  }4370  if (Op.getToken().empty()) {4371    Error(IDLoc, "instruction must have size higher than 0", EmptyRange,4372          MatchingInlineAsm);4373    return true;4374  }4375 4376  // FIXME: Ideally, we would only attempt suffix matches for things which are4377  // valid prefixes, and we could just infer the right unambiguous4378  // type. However, that requires substantially more matcher support than the4379  // following hack.4380 4381  // Change the operand to point to a temporary token.4382  StringRef Base = Op.getToken();4383  SmallString<16> Tmp;4384  Tmp += Base;4385  Tmp += ' ';4386  Op.setTokenValue(Tmp);4387 4388  // If this instruction starts with an 'f', then it is a floating point stack4389  // instruction.  These come in up to three forms for 32-bit, 64-bit, and4390  // 80-bit floating point, which use the suffixes s,l,t respectively.4391  //4392  // Otherwise, we assume that this may be an integer instruction, which comes4393  // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.4394  const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";4395  // MemSize corresponding to Suffixes.  { 8, 16, 32, 64 }    { 32, 64, 80, 0 }4396  const char *MemSize = Base[0] != 'f' ? "\x08\x10\x20\x40" : "\x20\x40\x50\0";4397 4398  // Check for the various suffix matches.4399  uint64_t ErrorInfoIgnore;4400  FeatureBitset ErrorInfoMissingFeatures; // Init suppresses compiler warnings.4401  unsigned Match[4];4402 4403  // Some instruction like VPMULDQ is NOT the variant of VPMULD but a new one.4404  // So we should make sure the suffix matcher only works for memory variant4405  // that has the same size with the suffix.4406  // FIXME: This flag is a workaround for legacy instructions that didn't4407  // declare non suffix variant assembly.4408  bool HasVectorReg = false;4409  X86Operand *MemOp = nullptr;4410  for (const auto &Op : Operands) {4411    X86Operand *X86Op = static_cast<X86Operand *>(Op.get());4412    if (X86Op->isVectorReg())4413      HasVectorReg = true;4414    else if (X86Op->isMem()) {4415      MemOp = X86Op;4416      assert(MemOp->Mem.Size == 0 && "Memory size always 0 under ATT syntax");4417      // Have we found an unqualified memory operand,4418      // break. IA allows only one memory operand.4419      break;4420    }4421  }4422 4423  for (unsigned I = 0, E = std::size(Match); I != E; ++I) {4424    Tmp.back() = Suffixes[I];4425    if (MemOp && HasVectorReg)4426      MemOp->Mem.Size = MemSize[I];4427    Match[I] = Match_MnemonicFail;4428    if (MemOp || !HasVectorReg) {4429      Match[I] =4430          MatchInstruction(Operands, Inst, ErrorInfoIgnore, MissingFeatures,4431                           MatchingInlineAsm, isParsingIntelSyntax());4432      // If this returned as a missing feature failure, remember that.4433      if (Match[I] == Match_MissingFeature)4434        ErrorInfoMissingFeatures = MissingFeatures;4435    }4436  }4437 4438  // Restore the old token.4439  Op.setTokenValue(Base);4440 4441  // If exactly one matched, then we treat that as a successful match (and the4442  // instruction will already have been filled in correctly, since the failing4443  // matches won't have modified it).4444  unsigned NumSuccessfulMatches = llvm::count(Match, Match_Success);4445  if (NumSuccessfulMatches == 1) {4446    if (!MatchingInlineAsm && validateInstruction(Inst, Operands))4447      return true;4448    // Some instructions need post-processing to, for example, tweak which4449    // encoding is selected. Loop on it while changes happen so the4450    // individual transformations can chain off each other.4451    if (!MatchingInlineAsm)4452      while (processInstruction(Inst, Operands))4453        ;4454 4455    Inst.setLoc(IDLoc);4456    if (!MatchingInlineAsm)4457      emitInstruction(Inst, Operands, Out);4458    Opcode = Inst.getOpcode();4459    return false;4460  }4461 4462  // Otherwise, the match failed, try to produce a decent error message.4463 4464  // If we had multiple suffix matches, then identify this as an ambiguous4465  // match.4466  if (NumSuccessfulMatches > 1) {4467    char MatchChars[4];4468    unsigned NumMatches = 0;4469    for (unsigned I = 0, E = std::size(Match); I != E; ++I)4470      if (Match[I] == Match_Success)4471        MatchChars[NumMatches++] = Suffixes[I];4472 4473    SmallString<126> Msg;4474    raw_svector_ostream OS(Msg);4475    OS << "ambiguous instructions require an explicit suffix (could be ";4476    for (unsigned i = 0; i != NumMatches; ++i) {4477      if (i != 0)4478        OS << ", ";4479      if (i + 1 == NumMatches)4480        OS << "or ";4481      OS << "'" << Base << MatchChars[i] << "'";4482    }4483    OS << ")";4484    Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);4485    return true;4486  }4487 4488  // Okay, we know that none of the variants matched successfully.4489 4490  // If all of the instructions reported an invalid mnemonic, then the original4491  // mnemonic was invalid.4492  if (llvm::count(Match, Match_MnemonicFail) == 4) {4493    if (OriginalError == Match_MnemonicFail)4494      return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",4495                   Op.getLocRange(), MatchingInlineAsm);4496 4497    if (OriginalError == Match_Unsupported)4498      return Error(IDLoc, "unsupported instruction", EmptyRange,4499                   MatchingInlineAsm);4500 4501    assert(OriginalError == Match_InvalidOperand && "Unexpected error");4502    // Recover location info for the operand if we know which was the problem.4503    if (ErrorInfo != ~0ULL) {4504      if (ErrorInfo >= Operands.size())4505        return Error(IDLoc, "too few operands for instruction", EmptyRange,4506                     MatchingInlineAsm);4507 4508      X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];4509      if (Operand.getStartLoc().isValid()) {4510        SMRange OperandRange = Operand.getLocRange();4511        return Error(Operand.getStartLoc(), "invalid operand for instruction",4512                     OperandRange, MatchingInlineAsm);4513      }4514    }4515 4516    return Error(IDLoc, "invalid operand for instruction", EmptyRange,4517                 MatchingInlineAsm);4518  }4519 4520  // If one instruction matched as unsupported, report this as unsupported.4521  if (llvm::count(Match, Match_Unsupported) == 1) {4522    return Error(IDLoc, "unsupported instruction", EmptyRange,4523                 MatchingInlineAsm);4524  }4525 4526  // If one instruction matched with a missing feature, report this as a4527  // missing feature.4528  if (llvm::count(Match, Match_MissingFeature) == 1) {4529    ErrorInfo = Match_MissingFeature;4530    return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,4531                               MatchingInlineAsm);4532  }4533 4534  // If one instruction matched with an invalid operand, report this as an4535  // operand failure.4536  if (llvm::count(Match, Match_InvalidOperand) == 1) {4537    return Error(IDLoc, "invalid operand for instruction", EmptyRange,4538                 MatchingInlineAsm);4539  }4540 4541  // If all of these were an outright failure, report it in a useless way.4542  Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",4543        EmptyRange, MatchingInlineAsm);4544  return true;4545}4546 4547bool X86AsmParser::matchAndEmitIntelInstruction(4548    SMLoc IDLoc, unsigned &Opcode, MCInst &Inst, OperandVector &Operands,4549    MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm) {4550  X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);4551  SMRange EmptyRange;4552  // Find one unsized memory operand, if present.4553  X86Operand *UnsizedMemOp = nullptr;4554  for (const auto &Op : Operands) {4555    X86Operand *X86Op = static_cast<X86Operand *>(Op.get());4556    if (X86Op->isMemUnsized()) {4557      UnsizedMemOp = X86Op;4558      // Have we found an unqualified memory operand,4559      // break. IA allows only one memory operand.4560      break;4561    }4562  }4563 4564  // Allow some instructions to have implicitly pointer-sized operands.  This is4565  // compatible with gas.4566  StringRef Mnemonic = (static_cast<X86Operand &>(*Operands[0])).getToken();4567  if (UnsizedMemOp) {4568    static const char *const PtrSizedInstrs[] = {"call", "jmp", "push", "pop"};4569    for (const char *Instr : PtrSizedInstrs) {4570      if (Mnemonic == Instr) {4571        UnsizedMemOp->Mem.Size = getPointerWidth();4572        break;4573      }4574    }4575  }4576 4577  SmallVector<unsigned, 8> Match;4578  FeatureBitset ErrorInfoMissingFeatures;4579  FeatureBitset MissingFeatures;4580  StringRef Base = (static_cast<X86Operand &>(*Operands[0])).getToken();4581 4582  // If unsized push has immediate operand we should default the default pointer4583  // size for the size.4584  if (Mnemonic == "push" && Operands.size() == 2) {4585    auto *X86Op = static_cast<X86Operand *>(Operands[1].get());4586    if (X86Op->isImm()) {4587      // If it's not a constant fall through and let remainder take care of it.4588      const auto *CE = dyn_cast<MCConstantExpr>(X86Op->getImm());4589      unsigned Size = getPointerWidth();4590      if (CE &&4591          (isIntN(Size, CE->getValue()) || isUIntN(Size, CE->getValue()))) {4592        SmallString<16> Tmp;4593        Tmp += Base;4594        Tmp += (is64BitMode())4595                   ? "q"4596                   : (is32BitMode()) ? "l" : (is16BitMode()) ? "w" : " ";4597        Op.setTokenValue(Tmp);4598        // Do match in ATT mode to allow explicit suffix usage.4599        Match.push_back(MatchInstruction(Operands, Inst, ErrorInfo,4600                                         MissingFeatures, MatchingInlineAsm,4601                                         false /*isParsingIntelSyntax()*/));4602        Op.setTokenValue(Base);4603      }4604    }4605  }4606 4607  // If an unsized memory operand is present, try to match with each memory4608  // operand size.  In Intel assembly, the size is not part of the instruction4609  // mnemonic.4610  if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {4611    static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};4612    for (unsigned Size : MopSizes) {4613      UnsizedMemOp->Mem.Size = Size;4614      uint64_t ErrorInfoIgnore;4615      unsigned LastOpcode = Inst.getOpcode();4616      unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore,4617                                    MissingFeatures, MatchingInlineAsm,4618                                    isParsingIntelSyntax());4619      if (Match.empty() || LastOpcode != Inst.getOpcode())4620        Match.push_back(M);4621 4622      // If this returned as a missing feature failure, remember that.4623      if (Match.back() == Match_MissingFeature)4624        ErrorInfoMissingFeatures = MissingFeatures;4625    }4626 4627    // Restore the size of the unsized memory operand if we modified it.4628    UnsizedMemOp->Mem.Size = 0;4629  }4630 4631  // If we haven't matched anything yet, this is not a basic integer or FPU4632  // operation.  There shouldn't be any ambiguity in our mnemonic table, so try4633  // matching with the unsized operand.4634  if (Match.empty()) {4635    Match.push_back(MatchInstruction(4636        Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,4637        isParsingIntelSyntax()));4638    // If this returned as a missing feature failure, remember that.4639    if (Match.back() == Match_MissingFeature)4640      ErrorInfoMissingFeatures = MissingFeatures;4641  }4642 4643  // Restore the size of the unsized memory operand if we modified it.4644  if (UnsizedMemOp)4645    UnsizedMemOp->Mem.Size = 0;4646 4647  // If it's a bad mnemonic, all results will be the same.4648  if (Match.back() == Match_MnemonicFail) {4649    return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",4650                 Op.getLocRange(), MatchingInlineAsm);4651  }4652 4653  unsigned NumSuccessfulMatches = llvm::count(Match, Match_Success);4654 4655  // If matching was ambiguous and we had size information from the frontend,4656  // try again with that. This handles cases like "movxz eax, m8/m16".4657  if (UnsizedMemOp && NumSuccessfulMatches > 1 &&4658      UnsizedMemOp->getMemFrontendSize()) {4659    UnsizedMemOp->Mem.Size = UnsizedMemOp->getMemFrontendSize();4660    unsigned M = MatchInstruction(4661        Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,4662        isParsingIntelSyntax());4663    if (M == Match_Success)4664      NumSuccessfulMatches = 1;4665 4666    // Add a rewrite that encodes the size information we used from the4667    // frontend.4668    InstInfo->AsmRewrites->emplace_back(4669        AOK_SizeDirective, UnsizedMemOp->getStartLoc(),4670        /*Len=*/0, UnsizedMemOp->getMemFrontendSize());4671  }4672 4673  // If exactly one matched, then we treat that as a successful match (and the4674  // instruction will already have been filled in correctly, since the failing4675  // matches won't have modified it).4676  if (NumSuccessfulMatches == 1) {4677    if (!MatchingInlineAsm && validateInstruction(Inst, Operands))4678      return true;4679    // Some instructions need post-processing to, for example, tweak which4680    // encoding is selected. Loop on it while changes happen so the individual4681    // transformations can chain off each other.4682    if (!MatchingInlineAsm)4683      while (processInstruction(Inst, Operands))4684        ;4685    Inst.setLoc(IDLoc);4686    if (!MatchingInlineAsm)4687      emitInstruction(Inst, Operands, Out);4688    Opcode = Inst.getOpcode();4689    return false;4690  } else if (NumSuccessfulMatches > 1) {4691    assert(UnsizedMemOp &&4692           "multiple matches only possible with unsized memory operands");4693    return Error(UnsizedMemOp->getStartLoc(),4694                 "ambiguous operand size for instruction '" + Mnemonic + "\'",4695                 UnsizedMemOp->getLocRange());4696  }4697 4698  // If one instruction matched as unsupported, report this as unsupported.4699  if (llvm::count(Match, Match_Unsupported) == 1) {4700    return Error(IDLoc, "unsupported instruction", EmptyRange,4701                 MatchingInlineAsm);4702  }4703 4704  // If one instruction matched with a missing feature, report this as a4705  // missing feature.4706  if (llvm::count(Match, Match_MissingFeature) == 1) {4707    ErrorInfo = Match_MissingFeature;4708    return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,4709                               MatchingInlineAsm);4710  }4711 4712  // If one instruction matched with an invalid operand, report this as an4713  // operand failure.4714  if (llvm::count(Match, Match_InvalidOperand) == 1) {4715    return Error(IDLoc, "invalid operand for instruction", EmptyRange,4716                 MatchingInlineAsm);4717  }4718 4719  if (llvm::count(Match, Match_InvalidImmUnsignedi4) == 1) {4720    SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();4721    if (ErrorLoc == SMLoc())4722      ErrorLoc = IDLoc;4723    return Error(ErrorLoc, "immediate must be an integer in range [0, 15]",4724                 EmptyRange, MatchingInlineAsm);4725  }4726 4727  // If all of these were an outright failure, report it in a useless way.4728  return Error(IDLoc, "unknown instruction mnemonic", EmptyRange,4729               MatchingInlineAsm);4730}4731 4732bool X86AsmParser::omitRegisterFromClobberLists(MCRegister Reg) {4733  return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(Reg);4734}4735 4736bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {4737  MCAsmParser &Parser = getParser();4738  StringRef IDVal = DirectiveID.getIdentifier();4739  if (IDVal.starts_with(".arch"))4740    return parseDirectiveArch();4741  if (IDVal.starts_with(".code"))4742    return ParseDirectiveCode(IDVal, DirectiveID.getLoc());4743  else if (IDVal.starts_with(".att_syntax")) {4744    if (getLexer().isNot(AsmToken::EndOfStatement)) {4745      if (Parser.getTok().getString() == "prefix")4746        Parser.Lex();4747      else if (Parser.getTok().getString() == "noprefix")4748        return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "4749                                           "supported: registers must have a "4750                                           "'%' prefix in .att_syntax");4751    }4752    getParser().setAssemblerDialect(0);4753    return false;4754  } else if (IDVal.starts_with(".intel_syntax")) {4755    getParser().setAssemblerDialect(1);4756    if (getLexer().isNot(AsmToken::EndOfStatement)) {4757      if (Parser.getTok().getString() == "noprefix")4758        Parser.Lex();4759      else if (Parser.getTok().getString() == "prefix")4760        return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "4761                                           "supported: registers must not have "4762                                           "a '%' prefix in .intel_syntax");4763    }4764    return false;4765  } else if (IDVal == ".nops")4766    return parseDirectiveNops(DirectiveID.getLoc());4767  else if (IDVal == ".even")4768    return parseDirectiveEven(DirectiveID.getLoc());4769  else if (IDVal == ".cv_fpo_proc")4770    return parseDirectiveFPOProc(DirectiveID.getLoc());4771  else if (IDVal == ".cv_fpo_setframe")4772    return parseDirectiveFPOSetFrame(DirectiveID.getLoc());4773  else if (IDVal == ".cv_fpo_pushreg")4774    return parseDirectiveFPOPushReg(DirectiveID.getLoc());4775  else if (IDVal == ".cv_fpo_stackalloc")4776    return parseDirectiveFPOStackAlloc(DirectiveID.getLoc());4777  else if (IDVal == ".cv_fpo_stackalign")4778    return parseDirectiveFPOStackAlign(DirectiveID.getLoc());4779  else if (IDVal == ".cv_fpo_endprologue")4780    return parseDirectiveFPOEndPrologue(DirectiveID.getLoc());4781  else if (IDVal == ".cv_fpo_endproc")4782    return parseDirectiveFPOEndProc(DirectiveID.getLoc());4783  else if (IDVal == ".seh_pushreg" ||4784           (Parser.isParsingMasm() && IDVal.equals_insensitive(".pushreg")))4785    return parseDirectiveSEHPushReg(DirectiveID.getLoc());4786  else if (IDVal == ".seh_setframe" ||4787           (Parser.isParsingMasm() && IDVal.equals_insensitive(".setframe")))4788    return parseDirectiveSEHSetFrame(DirectiveID.getLoc());4789  else if (IDVal == ".seh_savereg" ||4790           (Parser.isParsingMasm() && IDVal.equals_insensitive(".savereg")))4791    return parseDirectiveSEHSaveReg(DirectiveID.getLoc());4792  else if (IDVal == ".seh_savexmm" ||4793           (Parser.isParsingMasm() && IDVal.equals_insensitive(".savexmm128")))4794    return parseDirectiveSEHSaveXMM(DirectiveID.getLoc());4795  else if (IDVal == ".seh_pushframe" ||4796           (Parser.isParsingMasm() && IDVal.equals_insensitive(".pushframe")))4797    return parseDirectiveSEHPushFrame(DirectiveID.getLoc());4798 4799  return true;4800}4801 4802bool X86AsmParser::parseDirectiveArch() {4803  // Ignore .arch for now.4804  getParser().parseStringToEndOfStatement();4805  return false;4806}4807 4808/// parseDirectiveNops4809///  ::= .nops size[, control]4810bool X86AsmParser::parseDirectiveNops(SMLoc L) {4811  int64_t NumBytes = 0, Control = 0;4812  SMLoc NumBytesLoc, ControlLoc;4813  const MCSubtargetInfo& STI = getSTI();4814  NumBytesLoc = getTok().getLoc();4815  if (getParser().checkForValidSection() ||4816      getParser().parseAbsoluteExpression(NumBytes))4817    return true;4818 4819  if (parseOptionalToken(AsmToken::Comma)) {4820    ControlLoc = getTok().getLoc();4821    if (getParser().parseAbsoluteExpression(Control))4822      return true;4823  }4824  if (getParser().parseEOL())4825    return true;4826 4827  if (NumBytes <= 0) {4828    Error(NumBytesLoc, "'.nops' directive with non-positive size");4829    return false;4830  }4831 4832  if (Control < 0) {4833    Error(ControlLoc, "'.nops' directive with negative NOP size");4834    return false;4835  }4836 4837  /// Emit nops4838  getParser().getStreamer().emitNops(NumBytes, Control, L, STI);4839 4840  return false;4841}4842 4843/// parseDirectiveEven4844///  ::= .even4845bool X86AsmParser::parseDirectiveEven(SMLoc L) {4846  if (parseEOL())4847    return false;4848 4849  const MCSection *Section = getStreamer().getCurrentSectionOnly();4850  if (!Section) {4851    getStreamer().initSections(false, getSTI());4852    Section = getStreamer().getCurrentSectionOnly();4853  }4854  if (getContext().getAsmInfo()->useCodeAlign(*Section))4855    getStreamer().emitCodeAlignment(Align(2), &getSTI(), 0);4856  else4857    getStreamer().emitValueToAlignment(Align(2), 0, 1, 0);4858  return false;4859}4860 4861/// ParseDirectiveCode4862///  ::= .code16 | .code32 | .code644863bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {4864  MCAsmParser &Parser = getParser();4865  Code16GCC = false;4866  if (IDVal == ".code16") {4867    Parser.Lex();4868    if (!is16BitMode()) {4869      SwitchMode(X86::Is16Bit);4870      getTargetStreamer().emitCode16();4871    }4872  } else if (IDVal == ".code16gcc") {4873    // .code16gcc parses as if in 32-bit mode, but emits code in 16-bit mode.4874    Parser.Lex();4875    Code16GCC = true;4876    if (!is16BitMode()) {4877      SwitchMode(X86::Is16Bit);4878      getTargetStreamer().emitCode16();4879    }4880  } else if (IDVal == ".code32") {4881    Parser.Lex();4882    if (!is32BitMode()) {4883      SwitchMode(X86::Is32Bit);4884      getTargetStreamer().emitCode32();4885    }4886  } else if (IDVal == ".code64") {4887    Parser.Lex();4888    if (!is64BitMode()) {4889      SwitchMode(X86::Is64Bit);4890      getTargetStreamer().emitCode64();4891    }4892  } else {4893    Error(L, "unknown directive " + IDVal);4894    return false;4895  }4896 4897  return false;4898}4899 4900// .cv_fpo_proc foo4901bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {4902  MCAsmParser &Parser = getParser();4903  StringRef ProcName;4904  int64_t ParamsSize;4905  if (Parser.parseIdentifier(ProcName))4906    return Parser.TokError("expected symbol name");4907  if (Parser.parseIntToken(ParamsSize, "expected parameter byte count"))4908    return true;4909  if (!isUIntN(32, ParamsSize))4910    return Parser.TokError("parameters size out of range");4911  if (parseEOL())4912    return true;4913  MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);4914  return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);4915}4916 4917// .cv_fpo_setframe ebp4918bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {4919  MCRegister Reg;4920  SMLoc DummyLoc;4921  if (parseRegister(Reg, DummyLoc, DummyLoc) || parseEOL())4922    return true;4923  return getTargetStreamer().emitFPOSetFrame(Reg, L);4924}4925 4926// .cv_fpo_pushreg ebx4927bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {4928  MCRegister Reg;4929  SMLoc DummyLoc;4930  if (parseRegister(Reg, DummyLoc, DummyLoc) || parseEOL())4931    return true;4932  return getTargetStreamer().emitFPOPushReg(Reg, L);4933}4934 4935// .cv_fpo_stackalloc 204936bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {4937  MCAsmParser &Parser = getParser();4938  int64_t Offset;4939  if (Parser.parseIntToken(Offset, "expected offset") || parseEOL())4940    return true;4941  return getTargetStreamer().emitFPOStackAlloc(Offset, L);4942}4943 4944// .cv_fpo_stackalign 84945bool X86AsmParser::parseDirectiveFPOStackAlign(SMLoc L) {4946  MCAsmParser &Parser = getParser();4947  int64_t Offset;4948  if (Parser.parseIntToken(Offset, "expected offset") || parseEOL())4949    return true;4950  return getTargetStreamer().emitFPOStackAlign(Offset, L);4951}4952 4953// .cv_fpo_endprologue4954bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {4955  MCAsmParser &Parser = getParser();4956  if (Parser.parseEOL())4957    return true;4958  return getTargetStreamer().emitFPOEndPrologue(L);4959}4960 4961// .cv_fpo_endproc4962bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {4963  MCAsmParser &Parser = getParser();4964  if (Parser.parseEOL())4965    return true;4966  return getTargetStreamer().emitFPOEndProc(L);4967}4968 4969bool X86AsmParser::parseSEHRegisterNumber(unsigned RegClassID,4970                                          MCRegister &RegNo) {4971  SMLoc startLoc = getLexer().getLoc();4972  const MCRegisterInfo *MRI = getContext().getRegisterInfo();4973 4974  // Try parsing the argument as a register first.4975  if (getLexer().getTok().isNot(AsmToken::Integer)) {4976    SMLoc endLoc;4977    if (parseRegister(RegNo, startLoc, endLoc))4978      return true;4979 4980    if (!X86MCRegisterClasses[RegClassID].contains(RegNo)) {4981      return Error(startLoc,4982                   "register is not supported for use with this directive");4983    }4984  } else {4985    // Otherwise, an integer number matching the encoding of the desired4986    // register may appear.4987    int64_t EncodedReg;4988    if (getParser().parseAbsoluteExpression(EncodedReg))4989      return true;4990 4991    // The SEH register number is the same as the encoding register number. Map4992    // from the encoding back to the LLVM register number.4993    RegNo = MCRegister();4994    for (MCPhysReg Reg : X86MCRegisterClasses[RegClassID]) {4995      if (MRI->getEncodingValue(Reg) == EncodedReg) {4996        RegNo = Reg;4997        break;4998      }4999    }5000    if (!RegNo) {5001      return Error(startLoc,5002                   "incorrect register number for use with this directive");5003    }5004  }5005 5006  return false;5007}5008 5009bool X86AsmParser::parseDirectiveSEHPushReg(SMLoc Loc) {5010  MCRegister Reg;5011  if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg))5012    return true;5013 5014  if (getLexer().isNot(AsmToken::EndOfStatement))5015    return TokError("expected end of directive");5016 5017  getParser().Lex();5018  getStreamer().emitWinCFIPushReg(Reg, Loc);5019  return false;5020}5021 5022bool X86AsmParser::parseDirectiveSEHSetFrame(SMLoc Loc) {5023  MCRegister Reg;5024  int64_t Off;5025  if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg))5026    return true;5027  if (getLexer().isNot(AsmToken::Comma))5028    return TokError("you must specify a stack pointer offset");5029 5030  getParser().Lex();5031  if (getParser().parseAbsoluteExpression(Off))5032    return true;5033 5034  if (getLexer().isNot(AsmToken::EndOfStatement))5035    return TokError("expected end of directive");5036 5037  getParser().Lex();5038  getStreamer().emitWinCFISetFrame(Reg, Off, Loc);5039  return false;5040}5041 5042bool X86AsmParser::parseDirectiveSEHSaveReg(SMLoc Loc) {5043  MCRegister Reg;5044  int64_t Off;5045  if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg))5046    return true;5047  if (getLexer().isNot(AsmToken::Comma))5048    return TokError("you must specify an offset on the stack");5049 5050  getParser().Lex();5051  if (getParser().parseAbsoluteExpression(Off))5052    return true;5053 5054  if (getLexer().isNot(AsmToken::EndOfStatement))5055    return TokError("expected end of directive");5056 5057  getParser().Lex();5058  getStreamer().emitWinCFISaveReg(Reg, Off, Loc);5059  return false;5060}5061 5062bool X86AsmParser::parseDirectiveSEHSaveXMM(SMLoc Loc) {5063  MCRegister Reg;5064  int64_t Off;5065  if (parseSEHRegisterNumber(X86::VR128XRegClassID, Reg))5066    return true;5067  if (getLexer().isNot(AsmToken::Comma))5068    return TokError("you must specify an offset on the stack");5069 5070  getParser().Lex();5071  if (getParser().parseAbsoluteExpression(Off))5072    return true;5073 5074  if (getLexer().isNot(AsmToken::EndOfStatement))5075    return TokError("expected end of directive");5076 5077  getParser().Lex();5078  getStreamer().emitWinCFISaveXMM(Reg, Off, Loc);5079  return false;5080}5081 5082bool X86AsmParser::parseDirectiveSEHPushFrame(SMLoc Loc) {5083  bool Code = false;5084  StringRef CodeID;5085  if (getLexer().is(AsmToken::At)) {5086    SMLoc startLoc = getLexer().getLoc();5087    getParser().Lex();5088    if (!getParser().parseIdentifier(CodeID)) {5089      if (CodeID != "code")5090        return Error(startLoc, "expected @code");5091      Code = true;5092    }5093  }5094 5095  if (getLexer().isNot(AsmToken::EndOfStatement))5096    return TokError("expected end of directive");5097 5098  getParser().Lex();5099  getStreamer().emitWinCFIPushFrame(Code, Loc);5100  return false;5101}5102 5103// Force static initialization.5104extern "C" LLVM_C_ABI void LLVMInitializeX86AsmParser() {5105  RegisterMCAsmParser<X86AsmParser> X(getTheX86_32Target());5106  RegisterMCAsmParser<X86AsmParser> Y(getTheX86_64Target());5107}5108 5109#define GET_MATCHER_IMPLEMENTATION5110#include "X86GenAsmMatcher.inc"5111