xref: /openbsd-src/gnu/llvm/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
109467b48Spatrick //===-- X86AsmParser.cpp - Parse X86 assembly to MCInst instructions ------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick 
909467b48Spatrick #include "MCTargetDesc/X86BaseInfo.h"
1009467b48Spatrick #include "MCTargetDesc/X86IntelInstPrinter.h"
1109467b48Spatrick #include "MCTargetDesc/X86MCExpr.h"
12*d415bd75Srobert #include "MCTargetDesc/X86MCTargetDesc.h"
1309467b48Spatrick #include "MCTargetDesc/X86TargetStreamer.h"
1409467b48Spatrick #include "TargetInfo/X86TargetInfo.h"
1509467b48Spatrick #include "X86AsmParserCommon.h"
1609467b48Spatrick #include "X86Operand.h"
1709467b48Spatrick #include "llvm/ADT/STLExtras.h"
1809467b48Spatrick #include "llvm/ADT/SmallString.h"
1909467b48Spatrick #include "llvm/ADT/SmallVector.h"
2009467b48Spatrick #include "llvm/ADT/StringSwitch.h"
2109467b48Spatrick #include "llvm/ADT/Twine.h"
2209467b48Spatrick #include "llvm/MC/MCContext.h"
2309467b48Spatrick #include "llvm/MC/MCExpr.h"
2409467b48Spatrick #include "llvm/MC/MCInst.h"
2509467b48Spatrick #include "llvm/MC/MCInstrInfo.h"
2609467b48Spatrick #include "llvm/MC/MCParser/MCAsmLexer.h"
2709467b48Spatrick #include "llvm/MC/MCParser/MCAsmParser.h"
2809467b48Spatrick #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
2909467b48Spatrick #include "llvm/MC/MCParser/MCTargetAsmParser.h"
3009467b48Spatrick #include "llvm/MC/MCRegisterInfo.h"
3109467b48Spatrick #include "llvm/MC/MCSection.h"
3209467b48Spatrick #include "llvm/MC/MCStreamer.h"
3309467b48Spatrick #include "llvm/MC/MCSubtargetInfo.h"
3409467b48Spatrick #include "llvm/MC/MCSymbol.h"
35*d415bd75Srobert #include "llvm/MC/TargetRegistry.h"
36097a140dSpatrick #include "llvm/Support/CommandLine.h"
3773471bf0Spatrick #include "llvm/Support/Compiler.h"
3809467b48Spatrick #include "llvm/Support/SourceMgr.h"
3909467b48Spatrick #include "llvm/Support/raw_ostream.h"
4009467b48Spatrick #include <algorithm>
4109467b48Spatrick #include <memory>
4209467b48Spatrick 
4309467b48Spatrick using namespace llvm;
4409467b48Spatrick 
45097a140dSpatrick static cl::opt<bool> LVIInlineAsmHardening(
46097a140dSpatrick     "x86-experimental-lvi-inline-asm-hardening",
47097a140dSpatrick     cl::desc("Harden inline assembly code that may be vulnerable to Load Value"
48097a140dSpatrick              " Injection (LVI). This feature is experimental."), cl::Hidden);
49097a140dSpatrick 
checkScale(unsigned Scale,StringRef & ErrMsg)5009467b48Spatrick static bool checkScale(unsigned Scale, StringRef &ErrMsg) {
5109467b48Spatrick   if (Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
5209467b48Spatrick     ErrMsg = "scale factor in address must be 1, 2, 4 or 8";
5309467b48Spatrick     return true;
5409467b48Spatrick   }
5509467b48Spatrick   return false;
5609467b48Spatrick }
5709467b48Spatrick 
5809467b48Spatrick namespace {
5909467b48Spatrick 
6009467b48Spatrick static const char OpPrecedence[] = {
6109467b48Spatrick     0,  // IC_OR
6209467b48Spatrick     1,  // IC_XOR
6309467b48Spatrick     2,  // IC_AND
6473471bf0Spatrick     4,  // IC_LSHIFT
6573471bf0Spatrick     4,  // IC_RSHIFT
6673471bf0Spatrick     5,  // IC_PLUS
6773471bf0Spatrick     5,  // IC_MINUS
6873471bf0Spatrick     6,  // IC_MULTIPLY
6973471bf0Spatrick     6,  // IC_DIVIDE
7073471bf0Spatrick     6,  // IC_MOD
7173471bf0Spatrick     7,  // IC_NOT
7273471bf0Spatrick     8,  // IC_NEG
7373471bf0Spatrick     9,  // IC_RPAREN
7473471bf0Spatrick     10, // IC_LPAREN
7509467b48Spatrick     0,  // IC_IMM
7673471bf0Spatrick     0,  // IC_REGISTER
7773471bf0Spatrick     3,  // IC_EQ
7873471bf0Spatrick     3,  // IC_NE
7973471bf0Spatrick     3,  // IC_LT
8073471bf0Spatrick     3,  // IC_LE
8173471bf0Spatrick     3,  // IC_GT
8273471bf0Spatrick     3   // IC_GE
8309467b48Spatrick };
8409467b48Spatrick 
8509467b48Spatrick class X86AsmParser : public MCTargetAsmParser {
8609467b48Spatrick   ParseInstructionInfo *InstInfo;
8709467b48Spatrick   bool Code16GCC;
8873471bf0Spatrick   unsigned ForcedDataPrefix = 0;
8909467b48Spatrick 
9009467b48Spatrick   enum VEXEncoding {
9109467b48Spatrick     VEXEncoding_Default,
92097a140dSpatrick     VEXEncoding_VEX,
9373471bf0Spatrick     VEXEncoding_VEX2,
9409467b48Spatrick     VEXEncoding_VEX3,
9509467b48Spatrick     VEXEncoding_EVEX,
9609467b48Spatrick   };
9709467b48Spatrick 
9809467b48Spatrick   VEXEncoding ForcedVEXEncoding = VEXEncoding_Default;
9909467b48Spatrick 
10073471bf0Spatrick   enum DispEncoding {
10173471bf0Spatrick     DispEncoding_Default,
10273471bf0Spatrick     DispEncoding_Disp8,
10373471bf0Spatrick     DispEncoding_Disp32,
10473471bf0Spatrick   };
10573471bf0Spatrick 
10673471bf0Spatrick   DispEncoding ForcedDispEncoding = DispEncoding_Default;
10773471bf0Spatrick 
10809467b48Spatrick private:
consumeToken()10909467b48Spatrick   SMLoc consumeToken() {
11009467b48Spatrick     MCAsmParser &Parser = getParser();
11109467b48Spatrick     SMLoc Result = Parser.getTok().getLoc();
11209467b48Spatrick     Parser.Lex();
11309467b48Spatrick     return Result;
11409467b48Spatrick   }
11509467b48Spatrick 
getTargetStreamer()11609467b48Spatrick   X86TargetStreamer &getTargetStreamer() {
11709467b48Spatrick     assert(getParser().getStreamer().getTargetStreamer() &&
11809467b48Spatrick            "do not have a target streamer");
11909467b48Spatrick     MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
12009467b48Spatrick     return static_cast<X86TargetStreamer &>(TS);
12109467b48Spatrick   }
12209467b48Spatrick 
MatchInstruction(const OperandVector & Operands,MCInst & Inst,uint64_t & ErrorInfo,FeatureBitset & MissingFeatures,bool matchingInlineAsm,unsigned VariantID=0)12309467b48Spatrick   unsigned MatchInstruction(const OperandVector &Operands, MCInst &Inst,
12409467b48Spatrick                             uint64_t &ErrorInfo, FeatureBitset &MissingFeatures,
12509467b48Spatrick                             bool matchingInlineAsm, unsigned VariantID = 0) {
12609467b48Spatrick     // In Code16GCC mode, match as 32-bit.
12709467b48Spatrick     if (Code16GCC)
128*d415bd75Srobert       SwitchMode(X86::Is32Bit);
12909467b48Spatrick     unsigned rv = MatchInstructionImpl(Operands, Inst, ErrorInfo,
13009467b48Spatrick                                        MissingFeatures, matchingInlineAsm,
13109467b48Spatrick                                        VariantID);
13209467b48Spatrick     if (Code16GCC)
133*d415bd75Srobert       SwitchMode(X86::Is16Bit);
13409467b48Spatrick     return rv;
13509467b48Spatrick   }
13609467b48Spatrick 
13709467b48Spatrick   enum InfixCalculatorTok {
13809467b48Spatrick     IC_OR = 0,
13909467b48Spatrick     IC_XOR,
14009467b48Spatrick     IC_AND,
14109467b48Spatrick     IC_LSHIFT,
14209467b48Spatrick     IC_RSHIFT,
14309467b48Spatrick     IC_PLUS,
14409467b48Spatrick     IC_MINUS,
14509467b48Spatrick     IC_MULTIPLY,
14609467b48Spatrick     IC_DIVIDE,
14709467b48Spatrick     IC_MOD,
14809467b48Spatrick     IC_NOT,
14909467b48Spatrick     IC_NEG,
15009467b48Spatrick     IC_RPAREN,
15109467b48Spatrick     IC_LPAREN,
15209467b48Spatrick     IC_IMM,
15373471bf0Spatrick     IC_REGISTER,
15473471bf0Spatrick     IC_EQ,
15573471bf0Spatrick     IC_NE,
15673471bf0Spatrick     IC_LT,
15773471bf0Spatrick     IC_LE,
15873471bf0Spatrick     IC_GT,
15973471bf0Spatrick     IC_GE
16009467b48Spatrick   };
16109467b48Spatrick 
16209467b48Spatrick   enum IntelOperatorKind {
16309467b48Spatrick     IOK_INVALID = 0,
16409467b48Spatrick     IOK_LENGTH,
16509467b48Spatrick     IOK_SIZE,
16609467b48Spatrick     IOK_TYPE,
16709467b48Spatrick   };
16809467b48Spatrick 
16973471bf0Spatrick   enum MasmOperatorKind {
17073471bf0Spatrick     MOK_INVALID = 0,
17173471bf0Spatrick     MOK_LENGTHOF,
17273471bf0Spatrick     MOK_SIZEOF,
17373471bf0Spatrick     MOK_TYPE,
17473471bf0Spatrick   };
17573471bf0Spatrick 
17609467b48Spatrick   class InfixCalculator {
17709467b48Spatrick     typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
17809467b48Spatrick     SmallVector<InfixCalculatorTok, 4> InfixOperatorStack;
17909467b48Spatrick     SmallVector<ICToken, 4> PostfixStack;
18009467b48Spatrick 
isUnaryOperator(InfixCalculatorTok Op) const18173471bf0Spatrick     bool isUnaryOperator(InfixCalculatorTok Op) const {
18209467b48Spatrick       return Op == IC_NEG || Op == IC_NOT;
18309467b48Spatrick     }
18409467b48Spatrick 
18509467b48Spatrick   public:
popOperand()18609467b48Spatrick     int64_t popOperand() {
18709467b48Spatrick       assert (!PostfixStack.empty() && "Poped an empty stack!");
18809467b48Spatrick       ICToken Op = PostfixStack.pop_back_val();
18909467b48Spatrick       if (!(Op.first == IC_IMM || Op.first == IC_REGISTER))
19009467b48Spatrick         return -1; // The invalid Scale value will be caught later by checkScale
19109467b48Spatrick       return Op.second;
19209467b48Spatrick     }
pushOperand(InfixCalculatorTok Op,int64_t Val=0)19309467b48Spatrick     void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) {
19409467b48Spatrick       assert ((Op == IC_IMM || Op == IC_REGISTER) &&
19509467b48Spatrick               "Unexpected operand!");
19609467b48Spatrick       PostfixStack.push_back(std::make_pair(Op, Val));
19709467b48Spatrick     }
19809467b48Spatrick 
popOperator()19909467b48Spatrick     void popOperator() { InfixOperatorStack.pop_back(); }
pushOperator(InfixCalculatorTok Op)20009467b48Spatrick     void pushOperator(InfixCalculatorTok Op) {
20109467b48Spatrick       // Push the new operator if the stack is empty.
20209467b48Spatrick       if (InfixOperatorStack.empty()) {
20309467b48Spatrick         InfixOperatorStack.push_back(Op);
20409467b48Spatrick         return;
20509467b48Spatrick       }
20609467b48Spatrick 
20709467b48Spatrick       // Push the new operator if it has a higher precedence than the operator
20809467b48Spatrick       // on the top of the stack or the operator on the top of the stack is a
20909467b48Spatrick       // left parentheses.
21009467b48Spatrick       unsigned Idx = InfixOperatorStack.size() - 1;
21109467b48Spatrick       InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
21209467b48Spatrick       if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
21309467b48Spatrick         InfixOperatorStack.push_back(Op);
21409467b48Spatrick         return;
21509467b48Spatrick       }
21609467b48Spatrick 
21709467b48Spatrick       // The operator on the top of the stack has higher precedence than the
21809467b48Spatrick       // new operator.
21909467b48Spatrick       unsigned ParenCount = 0;
220*d415bd75Srobert       while (true) {
22109467b48Spatrick         // Nothing to process.
22209467b48Spatrick         if (InfixOperatorStack.empty())
22309467b48Spatrick           break;
22409467b48Spatrick 
22509467b48Spatrick         Idx = InfixOperatorStack.size() - 1;
22609467b48Spatrick         StackOp = InfixOperatorStack[Idx];
22709467b48Spatrick         if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount))
22809467b48Spatrick           break;
22909467b48Spatrick 
23009467b48Spatrick         // If we have an even parentheses count and we see a left parentheses,
23109467b48Spatrick         // then stop processing.
23209467b48Spatrick         if (!ParenCount && StackOp == IC_LPAREN)
23309467b48Spatrick           break;
23409467b48Spatrick 
23509467b48Spatrick         if (StackOp == IC_RPAREN) {
23609467b48Spatrick           ++ParenCount;
23709467b48Spatrick           InfixOperatorStack.pop_back();
23809467b48Spatrick         } else if (StackOp == IC_LPAREN) {
23909467b48Spatrick           --ParenCount;
24009467b48Spatrick           InfixOperatorStack.pop_back();
24109467b48Spatrick         } else {
24209467b48Spatrick           InfixOperatorStack.pop_back();
24309467b48Spatrick           PostfixStack.push_back(std::make_pair(StackOp, 0));
24409467b48Spatrick         }
24509467b48Spatrick       }
24609467b48Spatrick       // Push the new operator.
24709467b48Spatrick       InfixOperatorStack.push_back(Op);
24809467b48Spatrick     }
24909467b48Spatrick 
execute()25009467b48Spatrick     int64_t execute() {
25109467b48Spatrick       // Push any remaining operators onto the postfix stack.
25209467b48Spatrick       while (!InfixOperatorStack.empty()) {
25309467b48Spatrick         InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
25409467b48Spatrick         if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
25509467b48Spatrick           PostfixStack.push_back(std::make_pair(StackOp, 0));
25609467b48Spatrick       }
25709467b48Spatrick 
25809467b48Spatrick       if (PostfixStack.empty())
25909467b48Spatrick         return 0;
26009467b48Spatrick 
26109467b48Spatrick       SmallVector<ICToken, 16> OperandStack;
26209467b48Spatrick       for (unsigned i = 0, e = PostfixStack.size(); i != e; ++i) {
26309467b48Spatrick         ICToken Op = PostfixStack[i];
26409467b48Spatrick         if (Op.first == IC_IMM || Op.first == IC_REGISTER) {
26509467b48Spatrick           OperandStack.push_back(Op);
26609467b48Spatrick         } else if (isUnaryOperator(Op.first)) {
26709467b48Spatrick           assert (OperandStack.size() > 0 && "Too few operands.");
26809467b48Spatrick           ICToken Operand = OperandStack.pop_back_val();
26909467b48Spatrick           assert (Operand.first == IC_IMM &&
27009467b48Spatrick                   "Unary operation with a register!");
27109467b48Spatrick           switch (Op.first) {
27209467b48Spatrick           default:
27309467b48Spatrick             report_fatal_error("Unexpected operator!");
27409467b48Spatrick             break;
27509467b48Spatrick           case IC_NEG:
27609467b48Spatrick             OperandStack.push_back(std::make_pair(IC_IMM, -Operand.second));
27709467b48Spatrick             break;
27809467b48Spatrick           case IC_NOT:
27909467b48Spatrick             OperandStack.push_back(std::make_pair(IC_IMM, ~Operand.second));
28009467b48Spatrick             break;
28109467b48Spatrick           }
28209467b48Spatrick         } else {
28309467b48Spatrick           assert (OperandStack.size() > 1 && "Too few operands.");
28409467b48Spatrick           int64_t Val;
28509467b48Spatrick           ICToken Op2 = OperandStack.pop_back_val();
28609467b48Spatrick           ICToken Op1 = OperandStack.pop_back_val();
28709467b48Spatrick           switch (Op.first) {
28809467b48Spatrick           default:
28909467b48Spatrick             report_fatal_error("Unexpected operator!");
29009467b48Spatrick             break;
29109467b48Spatrick           case IC_PLUS:
29209467b48Spatrick             Val = Op1.second + Op2.second;
29309467b48Spatrick             OperandStack.push_back(std::make_pair(IC_IMM, Val));
29409467b48Spatrick             break;
29509467b48Spatrick           case IC_MINUS:
29609467b48Spatrick             Val = Op1.second - Op2.second;
29709467b48Spatrick             OperandStack.push_back(std::make_pair(IC_IMM, Val));
29809467b48Spatrick             break;
29909467b48Spatrick           case IC_MULTIPLY:
30009467b48Spatrick             assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
30109467b48Spatrick                     "Multiply operation with an immediate and a register!");
30209467b48Spatrick             Val = Op1.second * Op2.second;
30309467b48Spatrick             OperandStack.push_back(std::make_pair(IC_IMM, Val));
30409467b48Spatrick             break;
30509467b48Spatrick           case IC_DIVIDE:
30609467b48Spatrick             assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
30709467b48Spatrick                     "Divide operation with an immediate and a register!");
30809467b48Spatrick             assert (Op2.second != 0 && "Division by zero!");
30909467b48Spatrick             Val = Op1.second / Op2.second;
31009467b48Spatrick             OperandStack.push_back(std::make_pair(IC_IMM, Val));
31109467b48Spatrick             break;
31209467b48Spatrick           case IC_MOD:
31309467b48Spatrick             assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
31409467b48Spatrick                     "Modulo operation with an immediate and a register!");
31509467b48Spatrick             Val = Op1.second % Op2.second;
31609467b48Spatrick             OperandStack.push_back(std::make_pair(IC_IMM, Val));
31709467b48Spatrick             break;
31809467b48Spatrick           case IC_OR:
31909467b48Spatrick             assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
32009467b48Spatrick                     "Or operation with an immediate and a register!");
32109467b48Spatrick             Val = Op1.second | Op2.second;
32209467b48Spatrick             OperandStack.push_back(std::make_pair(IC_IMM, Val));
32309467b48Spatrick             break;
32409467b48Spatrick           case IC_XOR:
32509467b48Spatrick             assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
32609467b48Spatrick               "Xor operation with an immediate and a register!");
32709467b48Spatrick             Val = Op1.second ^ Op2.second;
32809467b48Spatrick             OperandStack.push_back(std::make_pair(IC_IMM, Val));
32909467b48Spatrick             break;
33009467b48Spatrick           case IC_AND:
33109467b48Spatrick             assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
33209467b48Spatrick                     "And operation with an immediate and a register!");
33309467b48Spatrick             Val = Op1.second & Op2.second;
33409467b48Spatrick             OperandStack.push_back(std::make_pair(IC_IMM, Val));
33509467b48Spatrick             break;
33609467b48Spatrick           case IC_LSHIFT:
33709467b48Spatrick             assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
33809467b48Spatrick                     "Left shift operation with an immediate and a register!");
33909467b48Spatrick             Val = Op1.second << Op2.second;
34009467b48Spatrick             OperandStack.push_back(std::make_pair(IC_IMM, Val));
34109467b48Spatrick             break;
34209467b48Spatrick           case IC_RSHIFT:
34309467b48Spatrick             assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
34409467b48Spatrick                     "Right shift operation with an immediate and a register!");
34509467b48Spatrick             Val = Op1.second >> Op2.second;
34609467b48Spatrick             OperandStack.push_back(std::make_pair(IC_IMM, Val));
34709467b48Spatrick             break;
34873471bf0Spatrick           case IC_EQ:
34973471bf0Spatrick             assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
35073471bf0Spatrick                    "Equals operation with an immediate and a register!");
35173471bf0Spatrick             Val = (Op1.second == Op2.second) ? -1 : 0;
35273471bf0Spatrick             OperandStack.push_back(std::make_pair(IC_IMM, Val));
35373471bf0Spatrick             break;
35473471bf0Spatrick           case IC_NE:
35573471bf0Spatrick             assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
35673471bf0Spatrick                    "Not-equals operation with an immediate and a register!");
35773471bf0Spatrick             Val = (Op1.second != Op2.second) ? -1 : 0;
35873471bf0Spatrick             OperandStack.push_back(std::make_pair(IC_IMM, Val));
35973471bf0Spatrick             break;
36073471bf0Spatrick           case IC_LT:
36173471bf0Spatrick             assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
36273471bf0Spatrick                    "Less-than operation with an immediate and a register!");
36373471bf0Spatrick             Val = (Op1.second < Op2.second) ? -1 : 0;
36473471bf0Spatrick             OperandStack.push_back(std::make_pair(IC_IMM, Val));
36573471bf0Spatrick             break;
36673471bf0Spatrick           case IC_LE:
36773471bf0Spatrick             assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
36873471bf0Spatrick                    "Less-than-or-equal operation with an immediate and a "
36973471bf0Spatrick                    "register!");
37073471bf0Spatrick             Val = (Op1.second <= Op2.second) ? -1 : 0;
37173471bf0Spatrick             OperandStack.push_back(std::make_pair(IC_IMM, Val));
37273471bf0Spatrick             break;
37373471bf0Spatrick           case IC_GT:
37473471bf0Spatrick             assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
37573471bf0Spatrick                    "Greater-than operation with an immediate and a register!");
37673471bf0Spatrick             Val = (Op1.second > Op2.second) ? -1 : 0;
37773471bf0Spatrick             OperandStack.push_back(std::make_pair(IC_IMM, Val));
37873471bf0Spatrick             break;
37973471bf0Spatrick           case IC_GE:
38073471bf0Spatrick             assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
38173471bf0Spatrick                    "Greater-than-or-equal operation with an immediate and a "
38273471bf0Spatrick                    "register!");
38373471bf0Spatrick             Val = (Op1.second >= Op2.second) ? -1 : 0;
38473471bf0Spatrick             OperandStack.push_back(std::make_pair(IC_IMM, Val));
38573471bf0Spatrick             break;
38609467b48Spatrick           }
38709467b48Spatrick         }
38809467b48Spatrick       }
38909467b48Spatrick       assert (OperandStack.size() == 1 && "Expected a single result.");
39009467b48Spatrick       return OperandStack.pop_back_val().second;
39109467b48Spatrick     }
39209467b48Spatrick   };
39309467b48Spatrick 
39409467b48Spatrick   enum IntelExprState {
39509467b48Spatrick     IES_INIT,
39609467b48Spatrick     IES_OR,
39709467b48Spatrick     IES_XOR,
39809467b48Spatrick     IES_AND,
39973471bf0Spatrick     IES_EQ,
40073471bf0Spatrick     IES_NE,
40173471bf0Spatrick     IES_LT,
40273471bf0Spatrick     IES_LE,
40373471bf0Spatrick     IES_GT,
40473471bf0Spatrick     IES_GE,
40509467b48Spatrick     IES_LSHIFT,
40609467b48Spatrick     IES_RSHIFT,
40709467b48Spatrick     IES_PLUS,
40809467b48Spatrick     IES_MINUS,
40909467b48Spatrick     IES_OFFSET,
410097a140dSpatrick     IES_CAST,
41109467b48Spatrick     IES_NOT,
41209467b48Spatrick     IES_MULTIPLY,
41309467b48Spatrick     IES_DIVIDE,
41409467b48Spatrick     IES_MOD,
41509467b48Spatrick     IES_LBRAC,
41609467b48Spatrick     IES_RBRAC,
41709467b48Spatrick     IES_LPAREN,
41809467b48Spatrick     IES_RPAREN,
41909467b48Spatrick     IES_REGISTER,
42009467b48Spatrick     IES_INTEGER,
42109467b48Spatrick     IES_IDENTIFIER,
42209467b48Spatrick     IES_ERROR
42309467b48Spatrick   };
42409467b48Spatrick 
42509467b48Spatrick   class IntelExprStateMachine {
426*d415bd75Srobert     IntelExprState State = IES_INIT, PrevState = IES_ERROR;
427*d415bd75Srobert     unsigned BaseReg = 0, IndexReg = 0, TmpReg = 0, Scale = 0;
428*d415bd75Srobert     int64_t Imm = 0;
429*d415bd75Srobert     const MCExpr *Sym = nullptr;
43009467b48Spatrick     StringRef SymName;
43109467b48Spatrick     InfixCalculator IC;
43209467b48Spatrick     InlineAsmIdentifierInfo Info;
433*d415bd75Srobert     short BracCount = 0;
434*d415bd75Srobert     bool MemExpr = false;
435*d415bd75Srobert     bool OffsetOperator = false;
436*d415bd75Srobert     bool AttachToOperandIdx = false;
437*d415bd75Srobert     bool IsPIC = false;
43809467b48Spatrick     SMLoc OffsetOperatorLoc;
43973471bf0Spatrick     AsmTypeInfo CurType;
44009467b48Spatrick 
setSymRef(const MCExpr * Val,StringRef ID,StringRef & ErrMsg)44109467b48Spatrick     bool setSymRef(const MCExpr *Val, StringRef ID, StringRef &ErrMsg) {
44209467b48Spatrick       if (Sym) {
44309467b48Spatrick         ErrMsg = "cannot use more than one symbol in memory operand";
44409467b48Spatrick         return true;
44509467b48Spatrick       }
44609467b48Spatrick       Sym = Val;
44709467b48Spatrick       SymName = ID;
44809467b48Spatrick       return false;
44909467b48Spatrick     }
45009467b48Spatrick 
45109467b48Spatrick   public:
452*d415bd75Srobert     IntelExprStateMachine() = default;
45309467b48Spatrick 
addImm(int64_t imm)45409467b48Spatrick     void addImm(int64_t imm) { Imm += imm; }
getBracCount() const45573471bf0Spatrick     short getBracCount() const { return BracCount; }
isMemExpr() const45673471bf0Spatrick     bool isMemExpr() const { return MemExpr; }
isOffsetOperator() const45773471bf0Spatrick     bool isOffsetOperator() const { return OffsetOperator; }
getOffsetLoc() const45873471bf0Spatrick     SMLoc getOffsetLoc() const { return OffsetOperatorLoc; }
getBaseReg() const45973471bf0Spatrick     unsigned getBaseReg() const { return BaseReg; }
getIndexReg() const46073471bf0Spatrick     unsigned getIndexReg() const { return IndexReg; }
getScale() const46173471bf0Spatrick     unsigned getScale() const { return Scale; }
getSym() const46273471bf0Spatrick     const MCExpr *getSym() const { return Sym; }
getSymName() const46373471bf0Spatrick     StringRef getSymName() const { return SymName; }
getType() const46473471bf0Spatrick     StringRef getType() const { return CurType.Name; }
getSize() const46573471bf0Spatrick     unsigned getSize() const { return CurType.Size; }
getElementSize() const46673471bf0Spatrick     unsigned getElementSize() const { return CurType.ElementSize; }
getLength() const46773471bf0Spatrick     unsigned getLength() const { return CurType.Length; }
getImm()46809467b48Spatrick     int64_t getImm() { return Imm + IC.execute(); }
isValidEndState() const46973471bf0Spatrick     bool isValidEndState() const {
47009467b48Spatrick       return State == IES_RBRAC || State == IES_INTEGER;
47109467b48Spatrick     }
472*d415bd75Srobert 
473*d415bd75Srobert     // Is the intel expression appended after an operand index.
474*d415bd75Srobert     // [OperandIdx][Intel Expression]
475*d415bd75Srobert     // This is neccessary for checking if it is an independent
476*d415bd75Srobert     // intel expression at back end when parse inline asm.
setAppendAfterOperand()477*d415bd75Srobert     void setAppendAfterOperand() { AttachToOperandIdx = true; }
478*d415bd75Srobert 
isPIC() const479*d415bd75Srobert     bool isPIC() const { return IsPIC; }
setPIC()480*d415bd75Srobert     void setPIC() { IsPIC = true; }
481*d415bd75Srobert 
hadError() const48273471bf0Spatrick     bool hadError() const { return State == IES_ERROR; }
getIdentifierInfo() const48373471bf0Spatrick     const InlineAsmIdentifierInfo &getIdentifierInfo() const { return Info; }
48409467b48Spatrick 
regsUseUpError(StringRef & ErrMsg)485*d415bd75Srobert     bool regsUseUpError(StringRef &ErrMsg) {
486*d415bd75Srobert       // This case mostly happen in inline asm, e.g. Arr[BaseReg + IndexReg]
487*d415bd75Srobert       // can not intruduce additional register in inline asm in PIC model.
488*d415bd75Srobert       if (IsPIC && AttachToOperandIdx)
489*d415bd75Srobert         ErrMsg = "Don't use 2 or more regs for mem offset in PIC model!";
490*d415bd75Srobert       else
491*d415bd75Srobert         ErrMsg = "BaseReg/IndexReg already set!";
492*d415bd75Srobert       return true;
493*d415bd75Srobert     }
494*d415bd75Srobert 
onOr()49509467b48Spatrick     void onOr() {
49609467b48Spatrick       IntelExprState CurrState = State;
49709467b48Spatrick       switch (State) {
49809467b48Spatrick       default:
49909467b48Spatrick         State = IES_ERROR;
50009467b48Spatrick         break;
50109467b48Spatrick       case IES_INTEGER:
50209467b48Spatrick       case IES_RPAREN:
50309467b48Spatrick       case IES_REGISTER:
50409467b48Spatrick         State = IES_OR;
50509467b48Spatrick         IC.pushOperator(IC_OR);
50609467b48Spatrick         break;
50709467b48Spatrick       }
50809467b48Spatrick       PrevState = CurrState;
50909467b48Spatrick     }
onXor()51009467b48Spatrick     void onXor() {
51109467b48Spatrick       IntelExprState CurrState = State;
51209467b48Spatrick       switch (State) {
51309467b48Spatrick       default:
51409467b48Spatrick         State = IES_ERROR;
51509467b48Spatrick         break;
51609467b48Spatrick       case IES_INTEGER:
51709467b48Spatrick       case IES_RPAREN:
51809467b48Spatrick       case IES_REGISTER:
51909467b48Spatrick         State = IES_XOR;
52009467b48Spatrick         IC.pushOperator(IC_XOR);
52109467b48Spatrick         break;
52209467b48Spatrick       }
52309467b48Spatrick       PrevState = CurrState;
52409467b48Spatrick     }
onAnd()52509467b48Spatrick     void onAnd() {
52609467b48Spatrick       IntelExprState CurrState = State;
52709467b48Spatrick       switch (State) {
52809467b48Spatrick       default:
52909467b48Spatrick         State = IES_ERROR;
53009467b48Spatrick         break;
53109467b48Spatrick       case IES_INTEGER:
53209467b48Spatrick       case IES_RPAREN:
53309467b48Spatrick       case IES_REGISTER:
53409467b48Spatrick         State = IES_AND;
53509467b48Spatrick         IC.pushOperator(IC_AND);
53609467b48Spatrick         break;
53709467b48Spatrick       }
53809467b48Spatrick       PrevState = CurrState;
53909467b48Spatrick     }
onEq()54073471bf0Spatrick     void onEq() {
54173471bf0Spatrick       IntelExprState CurrState = State;
54273471bf0Spatrick       switch (State) {
54373471bf0Spatrick       default:
54473471bf0Spatrick         State = IES_ERROR;
54573471bf0Spatrick         break;
54673471bf0Spatrick       case IES_INTEGER:
54773471bf0Spatrick       case IES_RPAREN:
54873471bf0Spatrick       case IES_REGISTER:
54973471bf0Spatrick         State = IES_EQ;
55073471bf0Spatrick         IC.pushOperator(IC_EQ);
55173471bf0Spatrick         break;
55273471bf0Spatrick       }
55373471bf0Spatrick       PrevState = CurrState;
55473471bf0Spatrick     }
onNE()55573471bf0Spatrick     void onNE() {
55673471bf0Spatrick       IntelExprState CurrState = State;
55773471bf0Spatrick       switch (State) {
55873471bf0Spatrick       default:
55973471bf0Spatrick         State = IES_ERROR;
56073471bf0Spatrick         break;
56173471bf0Spatrick       case IES_INTEGER:
56273471bf0Spatrick       case IES_RPAREN:
56373471bf0Spatrick       case IES_REGISTER:
56473471bf0Spatrick         State = IES_NE;
56573471bf0Spatrick         IC.pushOperator(IC_NE);
56673471bf0Spatrick         break;
56773471bf0Spatrick       }
56873471bf0Spatrick       PrevState = CurrState;
56973471bf0Spatrick     }
onLT()57073471bf0Spatrick     void onLT() {
57173471bf0Spatrick       IntelExprState CurrState = State;
57273471bf0Spatrick       switch (State) {
57373471bf0Spatrick       default:
57473471bf0Spatrick         State = IES_ERROR;
57573471bf0Spatrick         break;
57673471bf0Spatrick       case IES_INTEGER:
57773471bf0Spatrick       case IES_RPAREN:
57873471bf0Spatrick       case IES_REGISTER:
57973471bf0Spatrick         State = IES_LT;
58073471bf0Spatrick         IC.pushOperator(IC_LT);
58173471bf0Spatrick         break;
58273471bf0Spatrick       }
58373471bf0Spatrick       PrevState = CurrState;
58473471bf0Spatrick     }
onLE()58573471bf0Spatrick     void onLE() {
58673471bf0Spatrick       IntelExprState CurrState = State;
58773471bf0Spatrick       switch (State) {
58873471bf0Spatrick       default:
58973471bf0Spatrick         State = IES_ERROR;
59073471bf0Spatrick         break;
59173471bf0Spatrick       case IES_INTEGER:
59273471bf0Spatrick       case IES_RPAREN:
59373471bf0Spatrick       case IES_REGISTER:
59473471bf0Spatrick         State = IES_LE;
59573471bf0Spatrick         IC.pushOperator(IC_LE);
59673471bf0Spatrick         break;
59773471bf0Spatrick       }
59873471bf0Spatrick       PrevState = CurrState;
59973471bf0Spatrick     }
onGT()60073471bf0Spatrick     void onGT() {
60173471bf0Spatrick       IntelExprState CurrState = State;
60273471bf0Spatrick       switch (State) {
60373471bf0Spatrick       default:
60473471bf0Spatrick         State = IES_ERROR;
60573471bf0Spatrick         break;
60673471bf0Spatrick       case IES_INTEGER:
60773471bf0Spatrick       case IES_RPAREN:
60873471bf0Spatrick       case IES_REGISTER:
60973471bf0Spatrick         State = IES_GT;
61073471bf0Spatrick         IC.pushOperator(IC_GT);
61173471bf0Spatrick         break;
61273471bf0Spatrick       }
61373471bf0Spatrick       PrevState = CurrState;
61473471bf0Spatrick     }
onGE()61573471bf0Spatrick     void onGE() {
61673471bf0Spatrick       IntelExprState CurrState = State;
61773471bf0Spatrick       switch (State) {
61873471bf0Spatrick       default:
61973471bf0Spatrick         State = IES_ERROR;
62073471bf0Spatrick         break;
62173471bf0Spatrick       case IES_INTEGER:
62273471bf0Spatrick       case IES_RPAREN:
62373471bf0Spatrick       case IES_REGISTER:
62473471bf0Spatrick         State = IES_GE;
62573471bf0Spatrick         IC.pushOperator(IC_GE);
62673471bf0Spatrick         break;
62773471bf0Spatrick       }
62873471bf0Spatrick       PrevState = CurrState;
62973471bf0Spatrick     }
onLShift()63009467b48Spatrick     void onLShift() {
63109467b48Spatrick       IntelExprState CurrState = State;
63209467b48Spatrick       switch (State) {
63309467b48Spatrick       default:
63409467b48Spatrick         State = IES_ERROR;
63509467b48Spatrick         break;
63609467b48Spatrick       case IES_INTEGER:
63709467b48Spatrick       case IES_RPAREN:
63809467b48Spatrick       case IES_REGISTER:
63909467b48Spatrick         State = IES_LSHIFT;
64009467b48Spatrick         IC.pushOperator(IC_LSHIFT);
64109467b48Spatrick         break;
64209467b48Spatrick       }
64309467b48Spatrick       PrevState = CurrState;
64409467b48Spatrick     }
onRShift()64509467b48Spatrick     void onRShift() {
64609467b48Spatrick       IntelExprState CurrState = State;
64709467b48Spatrick       switch (State) {
64809467b48Spatrick       default:
64909467b48Spatrick         State = IES_ERROR;
65009467b48Spatrick         break;
65109467b48Spatrick       case IES_INTEGER:
65209467b48Spatrick       case IES_RPAREN:
65309467b48Spatrick       case IES_REGISTER:
65409467b48Spatrick         State = IES_RSHIFT;
65509467b48Spatrick         IC.pushOperator(IC_RSHIFT);
65609467b48Spatrick         break;
65709467b48Spatrick       }
65809467b48Spatrick       PrevState = CurrState;
65909467b48Spatrick     }
onPlus(StringRef & ErrMsg)66009467b48Spatrick     bool onPlus(StringRef &ErrMsg) {
66109467b48Spatrick       IntelExprState CurrState = State;
66209467b48Spatrick       switch (State) {
66309467b48Spatrick       default:
66409467b48Spatrick         State = IES_ERROR;
66509467b48Spatrick         break;
66609467b48Spatrick       case IES_INTEGER:
66709467b48Spatrick       case IES_RPAREN:
66809467b48Spatrick       case IES_REGISTER:
66909467b48Spatrick       case IES_OFFSET:
67009467b48Spatrick         State = IES_PLUS;
67109467b48Spatrick         IC.pushOperator(IC_PLUS);
67209467b48Spatrick         if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
67309467b48Spatrick           // If we already have a BaseReg, then assume this is the IndexReg with
67409467b48Spatrick           // no explicit scale.
67509467b48Spatrick           if (!BaseReg) {
67609467b48Spatrick             BaseReg = TmpReg;
67709467b48Spatrick           } else {
678*d415bd75Srobert             if (IndexReg)
679*d415bd75Srobert               return regsUseUpError(ErrMsg);
68009467b48Spatrick             IndexReg = TmpReg;
68109467b48Spatrick             Scale = 0;
68209467b48Spatrick           }
68309467b48Spatrick         }
68409467b48Spatrick         break;
68509467b48Spatrick       }
68609467b48Spatrick       PrevState = CurrState;
68709467b48Spatrick       return false;
68809467b48Spatrick     }
onMinus(StringRef & ErrMsg)68909467b48Spatrick     bool onMinus(StringRef &ErrMsg) {
69009467b48Spatrick       IntelExprState CurrState = State;
69109467b48Spatrick       switch (State) {
69209467b48Spatrick       default:
69309467b48Spatrick         State = IES_ERROR;
69409467b48Spatrick         break;
69509467b48Spatrick       case IES_OR:
69609467b48Spatrick       case IES_XOR:
69709467b48Spatrick       case IES_AND:
69873471bf0Spatrick       case IES_EQ:
69973471bf0Spatrick       case IES_NE:
70073471bf0Spatrick       case IES_LT:
70173471bf0Spatrick       case IES_LE:
70273471bf0Spatrick       case IES_GT:
70373471bf0Spatrick       case IES_GE:
70409467b48Spatrick       case IES_LSHIFT:
70509467b48Spatrick       case IES_RSHIFT:
70609467b48Spatrick       case IES_PLUS:
70709467b48Spatrick       case IES_NOT:
70809467b48Spatrick       case IES_MULTIPLY:
70909467b48Spatrick       case IES_DIVIDE:
71009467b48Spatrick       case IES_MOD:
71109467b48Spatrick       case IES_LPAREN:
71209467b48Spatrick       case IES_RPAREN:
71309467b48Spatrick       case IES_LBRAC:
71409467b48Spatrick       case IES_RBRAC:
71509467b48Spatrick       case IES_INTEGER:
71609467b48Spatrick       case IES_REGISTER:
71709467b48Spatrick       case IES_INIT:
71809467b48Spatrick       case IES_OFFSET:
71909467b48Spatrick         State = IES_MINUS;
72009467b48Spatrick         // push minus operator if it is not a negate operator
72109467b48Spatrick         if (CurrState == IES_REGISTER || CurrState == IES_RPAREN ||
72209467b48Spatrick             CurrState == IES_INTEGER  || CurrState == IES_RBRAC  ||
72309467b48Spatrick             CurrState == IES_OFFSET)
72409467b48Spatrick           IC.pushOperator(IC_MINUS);
72509467b48Spatrick         else if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
72609467b48Spatrick           // We have negate operator for Scale: it's illegal
72709467b48Spatrick           ErrMsg = "Scale can't be negative";
72809467b48Spatrick           return true;
72909467b48Spatrick         } else
73009467b48Spatrick           IC.pushOperator(IC_NEG);
73109467b48Spatrick         if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
73209467b48Spatrick           // If we already have a BaseReg, then assume this is the IndexReg with
73309467b48Spatrick           // no explicit scale.
73409467b48Spatrick           if (!BaseReg) {
73509467b48Spatrick             BaseReg = TmpReg;
73609467b48Spatrick           } else {
737*d415bd75Srobert             if (IndexReg)
738*d415bd75Srobert               return regsUseUpError(ErrMsg);
73909467b48Spatrick             IndexReg = TmpReg;
74009467b48Spatrick             Scale = 0;
74109467b48Spatrick           }
74209467b48Spatrick         }
74309467b48Spatrick         break;
74409467b48Spatrick       }
74509467b48Spatrick       PrevState = CurrState;
74609467b48Spatrick       return false;
74709467b48Spatrick     }
onNot()74809467b48Spatrick     void onNot() {
74909467b48Spatrick       IntelExprState CurrState = State;
75009467b48Spatrick       switch (State) {
75109467b48Spatrick       default:
75209467b48Spatrick         State = IES_ERROR;
75309467b48Spatrick         break;
75409467b48Spatrick       case IES_OR:
75509467b48Spatrick       case IES_XOR:
75609467b48Spatrick       case IES_AND:
75773471bf0Spatrick       case IES_EQ:
75873471bf0Spatrick       case IES_NE:
75973471bf0Spatrick       case IES_LT:
76073471bf0Spatrick       case IES_LE:
76173471bf0Spatrick       case IES_GT:
76273471bf0Spatrick       case IES_GE:
76309467b48Spatrick       case IES_LSHIFT:
76409467b48Spatrick       case IES_RSHIFT:
76509467b48Spatrick       case IES_PLUS:
76609467b48Spatrick       case IES_MINUS:
76709467b48Spatrick       case IES_NOT:
76809467b48Spatrick       case IES_MULTIPLY:
76909467b48Spatrick       case IES_DIVIDE:
77009467b48Spatrick       case IES_MOD:
77109467b48Spatrick       case IES_LPAREN:
77209467b48Spatrick       case IES_LBRAC:
77309467b48Spatrick       case IES_INIT:
77409467b48Spatrick         State = IES_NOT;
77509467b48Spatrick         IC.pushOperator(IC_NOT);
77609467b48Spatrick         break;
77709467b48Spatrick       }
77809467b48Spatrick       PrevState = CurrState;
77909467b48Spatrick     }
onRegister(unsigned Reg,StringRef & ErrMsg)78009467b48Spatrick     bool onRegister(unsigned Reg, StringRef &ErrMsg) {
78109467b48Spatrick       IntelExprState CurrState = State;
78209467b48Spatrick       switch (State) {
78309467b48Spatrick       default:
78409467b48Spatrick         State = IES_ERROR;
78509467b48Spatrick         break;
78609467b48Spatrick       case IES_PLUS:
78709467b48Spatrick       case IES_LPAREN:
78809467b48Spatrick       case IES_LBRAC:
78909467b48Spatrick         State = IES_REGISTER;
79009467b48Spatrick         TmpReg = Reg;
79109467b48Spatrick         IC.pushOperand(IC_REGISTER);
79209467b48Spatrick         break;
79309467b48Spatrick       case IES_MULTIPLY:
79409467b48Spatrick         // Index Register - Scale * Register
79509467b48Spatrick         if (PrevState == IES_INTEGER) {
796*d415bd75Srobert           if (IndexReg)
797*d415bd75Srobert             return regsUseUpError(ErrMsg);
79809467b48Spatrick           State = IES_REGISTER;
79909467b48Spatrick           IndexReg = Reg;
80009467b48Spatrick           // Get the scale and replace the 'Scale * Register' with '0'.
80109467b48Spatrick           Scale = IC.popOperand();
80209467b48Spatrick           if (checkScale(Scale, ErrMsg))
80309467b48Spatrick             return true;
80409467b48Spatrick           IC.pushOperand(IC_IMM);
80509467b48Spatrick           IC.popOperator();
80609467b48Spatrick         } else {
80709467b48Spatrick           State = IES_ERROR;
80809467b48Spatrick         }
80909467b48Spatrick         break;
81009467b48Spatrick       }
81109467b48Spatrick       PrevState = CurrState;
81209467b48Spatrick       return false;
81309467b48Spatrick     }
onIdentifierExpr(const MCExpr * SymRef,StringRef SymRefName,const InlineAsmIdentifierInfo & IDInfo,const AsmTypeInfo & Type,bool ParsingMSInlineAsm,StringRef & ErrMsg)81409467b48Spatrick     bool onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName,
81509467b48Spatrick                           const InlineAsmIdentifierInfo &IDInfo,
81673471bf0Spatrick                           const AsmTypeInfo &Type, bool ParsingMSInlineAsm,
81773471bf0Spatrick                           StringRef &ErrMsg) {
81809467b48Spatrick       // InlineAsm: Treat an enum value as an integer
819097a140dSpatrick       if (ParsingMSInlineAsm)
82009467b48Spatrick         if (IDInfo.isKind(InlineAsmIdentifierInfo::IK_EnumVal))
82109467b48Spatrick           return onInteger(IDInfo.Enum.EnumVal, ErrMsg);
82209467b48Spatrick       // Treat a symbolic constant like an integer
82309467b48Spatrick       if (auto *CE = dyn_cast<MCConstantExpr>(SymRef))
82409467b48Spatrick         return onInteger(CE->getValue(), ErrMsg);
82509467b48Spatrick       PrevState = State;
82609467b48Spatrick       switch (State) {
82709467b48Spatrick       default:
82809467b48Spatrick         State = IES_ERROR;
82909467b48Spatrick         break;
830097a140dSpatrick       case IES_CAST:
83109467b48Spatrick       case IES_PLUS:
83209467b48Spatrick       case IES_MINUS:
83309467b48Spatrick       case IES_NOT:
83409467b48Spatrick       case IES_INIT:
83509467b48Spatrick       case IES_LBRAC:
83673471bf0Spatrick       case IES_LPAREN:
83709467b48Spatrick         if (setSymRef(SymRef, SymRefName, ErrMsg))
83809467b48Spatrick           return true;
83909467b48Spatrick         MemExpr = true;
84009467b48Spatrick         State = IES_INTEGER;
84109467b48Spatrick         IC.pushOperand(IC_IMM);
842097a140dSpatrick         if (ParsingMSInlineAsm)
84309467b48Spatrick           Info = IDInfo;
84473471bf0Spatrick         setTypeInfo(Type);
84509467b48Spatrick         break;
84609467b48Spatrick       }
84709467b48Spatrick       return false;
84809467b48Spatrick     }
onInteger(int64_t TmpInt,StringRef & ErrMsg)84909467b48Spatrick     bool onInteger(int64_t TmpInt, StringRef &ErrMsg) {
85009467b48Spatrick       IntelExprState CurrState = State;
85109467b48Spatrick       switch (State) {
85209467b48Spatrick       default:
85309467b48Spatrick         State = IES_ERROR;
85409467b48Spatrick         break;
85509467b48Spatrick       case IES_PLUS:
85609467b48Spatrick       case IES_MINUS:
85709467b48Spatrick       case IES_NOT:
85809467b48Spatrick       case IES_OR:
85909467b48Spatrick       case IES_XOR:
86009467b48Spatrick       case IES_AND:
86173471bf0Spatrick       case IES_EQ:
86273471bf0Spatrick       case IES_NE:
86373471bf0Spatrick       case IES_LT:
86473471bf0Spatrick       case IES_LE:
86573471bf0Spatrick       case IES_GT:
86673471bf0Spatrick       case IES_GE:
86709467b48Spatrick       case IES_LSHIFT:
86809467b48Spatrick       case IES_RSHIFT:
86909467b48Spatrick       case IES_DIVIDE:
87009467b48Spatrick       case IES_MOD:
87109467b48Spatrick       case IES_MULTIPLY:
87209467b48Spatrick       case IES_LPAREN:
87309467b48Spatrick       case IES_INIT:
87409467b48Spatrick       case IES_LBRAC:
87509467b48Spatrick         State = IES_INTEGER;
87609467b48Spatrick         if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
87709467b48Spatrick           // Index Register - Register * Scale
878*d415bd75Srobert           if (IndexReg)
879*d415bd75Srobert             return regsUseUpError(ErrMsg);
88009467b48Spatrick           IndexReg = TmpReg;
88109467b48Spatrick           Scale = TmpInt;
88209467b48Spatrick           if (checkScale(Scale, ErrMsg))
88309467b48Spatrick             return true;
88409467b48Spatrick           // Get the scale and replace the 'Register * Scale' with '0'.
88509467b48Spatrick           IC.popOperator();
88609467b48Spatrick         } else {
88709467b48Spatrick           IC.pushOperand(IC_IMM, TmpInt);
88809467b48Spatrick         }
88909467b48Spatrick         break;
89009467b48Spatrick       }
89109467b48Spatrick       PrevState = CurrState;
89209467b48Spatrick       return false;
89309467b48Spatrick     }
onStar()89409467b48Spatrick     void onStar() {
89509467b48Spatrick       PrevState = State;
89609467b48Spatrick       switch (State) {
89709467b48Spatrick       default:
89809467b48Spatrick         State = IES_ERROR;
89909467b48Spatrick         break;
90009467b48Spatrick       case IES_INTEGER:
90109467b48Spatrick       case IES_REGISTER:
90209467b48Spatrick       case IES_RPAREN:
90309467b48Spatrick         State = IES_MULTIPLY;
90409467b48Spatrick         IC.pushOperator(IC_MULTIPLY);
90509467b48Spatrick         break;
90609467b48Spatrick       }
90709467b48Spatrick     }
onDivide()90809467b48Spatrick     void onDivide() {
90909467b48Spatrick       PrevState = State;
91009467b48Spatrick       switch (State) {
91109467b48Spatrick       default:
91209467b48Spatrick         State = IES_ERROR;
91309467b48Spatrick         break;
91409467b48Spatrick       case IES_INTEGER:
91509467b48Spatrick       case IES_RPAREN:
91609467b48Spatrick         State = IES_DIVIDE;
91709467b48Spatrick         IC.pushOperator(IC_DIVIDE);
91809467b48Spatrick         break;
91909467b48Spatrick       }
92009467b48Spatrick     }
onMod()92109467b48Spatrick     void onMod() {
92209467b48Spatrick       PrevState = State;
92309467b48Spatrick       switch (State) {
92409467b48Spatrick       default:
92509467b48Spatrick         State = IES_ERROR;
92609467b48Spatrick         break;
92709467b48Spatrick       case IES_INTEGER:
92809467b48Spatrick       case IES_RPAREN:
92909467b48Spatrick         State = IES_MOD;
93009467b48Spatrick         IC.pushOperator(IC_MOD);
93109467b48Spatrick         break;
93209467b48Spatrick       }
93309467b48Spatrick     }
onLBrac()93409467b48Spatrick     bool onLBrac() {
93509467b48Spatrick       if (BracCount)
93609467b48Spatrick         return true;
93709467b48Spatrick       PrevState = State;
93809467b48Spatrick       switch (State) {
93909467b48Spatrick       default:
94009467b48Spatrick         State = IES_ERROR;
94109467b48Spatrick         break;
94209467b48Spatrick       case IES_RBRAC:
94309467b48Spatrick       case IES_INTEGER:
94409467b48Spatrick       case IES_RPAREN:
94509467b48Spatrick         State = IES_PLUS;
94609467b48Spatrick         IC.pushOperator(IC_PLUS);
94773471bf0Spatrick         CurType.Length = 1;
94873471bf0Spatrick         CurType.Size = CurType.ElementSize;
94909467b48Spatrick         break;
95009467b48Spatrick       case IES_INIT:
951097a140dSpatrick       case IES_CAST:
95209467b48Spatrick         assert(!BracCount && "BracCount should be zero on parsing's start");
95309467b48Spatrick         State = IES_LBRAC;
95409467b48Spatrick         break;
95509467b48Spatrick       }
95609467b48Spatrick       MemExpr = true;
95709467b48Spatrick       BracCount++;
95809467b48Spatrick       return false;
95909467b48Spatrick     }
onRBrac(StringRef & ErrMsg)960*d415bd75Srobert     bool onRBrac(StringRef &ErrMsg) {
96109467b48Spatrick       IntelExprState CurrState = State;
96209467b48Spatrick       switch (State) {
96309467b48Spatrick       default:
96409467b48Spatrick         State = IES_ERROR;
96509467b48Spatrick         break;
96609467b48Spatrick       case IES_INTEGER:
96709467b48Spatrick       case IES_OFFSET:
96809467b48Spatrick       case IES_REGISTER:
96909467b48Spatrick       case IES_RPAREN:
970*d415bd75Srobert         if (BracCount-- != 1) {
971*d415bd75Srobert           ErrMsg = "unexpected bracket encountered";
97209467b48Spatrick           return true;
973*d415bd75Srobert         }
97409467b48Spatrick         State = IES_RBRAC;
97509467b48Spatrick         if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
97609467b48Spatrick           // If we already have a BaseReg, then assume this is the IndexReg with
97709467b48Spatrick           // no explicit scale.
97809467b48Spatrick           if (!BaseReg) {
97909467b48Spatrick             BaseReg = TmpReg;
98009467b48Spatrick           } else {
981*d415bd75Srobert             if (IndexReg)
982*d415bd75Srobert               return regsUseUpError(ErrMsg);
98309467b48Spatrick             IndexReg = TmpReg;
98409467b48Spatrick             Scale = 0;
98509467b48Spatrick           }
98609467b48Spatrick         }
98709467b48Spatrick         break;
98809467b48Spatrick       }
98909467b48Spatrick       PrevState = CurrState;
99009467b48Spatrick       return false;
99109467b48Spatrick     }
onLParen()99209467b48Spatrick     void onLParen() {
99309467b48Spatrick       IntelExprState CurrState = State;
99409467b48Spatrick       switch (State) {
99509467b48Spatrick       default:
99609467b48Spatrick         State = IES_ERROR;
99709467b48Spatrick         break;
99809467b48Spatrick       case IES_PLUS:
99909467b48Spatrick       case IES_MINUS:
100009467b48Spatrick       case IES_NOT:
100109467b48Spatrick       case IES_OR:
100209467b48Spatrick       case IES_XOR:
100309467b48Spatrick       case IES_AND:
100473471bf0Spatrick       case IES_EQ:
100573471bf0Spatrick       case IES_NE:
100673471bf0Spatrick       case IES_LT:
100773471bf0Spatrick       case IES_LE:
100873471bf0Spatrick       case IES_GT:
100973471bf0Spatrick       case IES_GE:
101009467b48Spatrick       case IES_LSHIFT:
101109467b48Spatrick       case IES_RSHIFT:
101209467b48Spatrick       case IES_MULTIPLY:
101309467b48Spatrick       case IES_DIVIDE:
101409467b48Spatrick       case IES_MOD:
101509467b48Spatrick       case IES_LPAREN:
101609467b48Spatrick       case IES_INIT:
101709467b48Spatrick       case IES_LBRAC:
101809467b48Spatrick         State = IES_LPAREN;
101909467b48Spatrick         IC.pushOperator(IC_LPAREN);
102009467b48Spatrick         break;
102109467b48Spatrick       }
102209467b48Spatrick       PrevState = CurrState;
102309467b48Spatrick     }
onRParen()102409467b48Spatrick     void onRParen() {
102509467b48Spatrick       PrevState = State;
102609467b48Spatrick       switch (State) {
102709467b48Spatrick       default:
102809467b48Spatrick         State = IES_ERROR;
102909467b48Spatrick         break;
103009467b48Spatrick       case IES_INTEGER:
103109467b48Spatrick       case IES_OFFSET:
103209467b48Spatrick       case IES_REGISTER:
1033097a140dSpatrick       case IES_RBRAC:
103409467b48Spatrick       case IES_RPAREN:
103509467b48Spatrick         State = IES_RPAREN;
103609467b48Spatrick         IC.pushOperator(IC_RPAREN);
103709467b48Spatrick         break;
103809467b48Spatrick       }
103909467b48Spatrick     }
onOffset(const MCExpr * Val,SMLoc OffsetLoc,StringRef ID,const InlineAsmIdentifierInfo & IDInfo,bool ParsingMSInlineAsm,StringRef & ErrMsg)104009467b48Spatrick     bool onOffset(const MCExpr *Val, SMLoc OffsetLoc, StringRef ID,
104173471bf0Spatrick                   const InlineAsmIdentifierInfo &IDInfo,
104273471bf0Spatrick                   bool ParsingMSInlineAsm, StringRef &ErrMsg) {
104309467b48Spatrick       PrevState = State;
104409467b48Spatrick       switch (State) {
104509467b48Spatrick       default:
104609467b48Spatrick         ErrMsg = "unexpected offset operator expression";
104709467b48Spatrick         return true;
104809467b48Spatrick       case IES_PLUS:
104909467b48Spatrick       case IES_INIT:
105009467b48Spatrick       case IES_LBRAC:
105109467b48Spatrick         if (setSymRef(Val, ID, ErrMsg))
105209467b48Spatrick           return true;
105309467b48Spatrick         OffsetOperator = true;
105409467b48Spatrick         OffsetOperatorLoc = OffsetLoc;
105509467b48Spatrick         State = IES_OFFSET;
105609467b48Spatrick         // As we cannot yet resolve the actual value (offset), we retain
105709467b48Spatrick         // the requested semantics by pushing a '0' to the operands stack
105809467b48Spatrick         IC.pushOperand(IC_IMM);
1059097a140dSpatrick         if (ParsingMSInlineAsm) {
106009467b48Spatrick           Info = IDInfo;
106109467b48Spatrick         }
106209467b48Spatrick         break;
106309467b48Spatrick       }
106409467b48Spatrick       return false;
106509467b48Spatrick     }
onCast(AsmTypeInfo Info)106673471bf0Spatrick     void onCast(AsmTypeInfo Info) {
1067097a140dSpatrick       PrevState = State;
1068097a140dSpatrick       switch (State) {
1069097a140dSpatrick       default:
1070097a140dSpatrick         State = IES_ERROR;
1071097a140dSpatrick         break;
1072097a140dSpatrick       case IES_LPAREN:
107373471bf0Spatrick         setTypeInfo(Info);
1074097a140dSpatrick         State = IES_CAST;
1075097a140dSpatrick         break;
1076097a140dSpatrick       }
1077097a140dSpatrick     }
setTypeInfo(AsmTypeInfo Type)107873471bf0Spatrick     void setTypeInfo(AsmTypeInfo Type) { CurType = Type; }
107909467b48Spatrick   };
108009467b48Spatrick 
Error(SMLoc L,const Twine & Msg,SMRange Range=std::nullopt,bool MatchingInlineAsm=false)1081*d415bd75Srobert   bool Error(SMLoc L, const Twine &Msg, SMRange Range = std::nullopt,
108209467b48Spatrick              bool MatchingInlineAsm = false) {
108309467b48Spatrick     MCAsmParser &Parser = getParser();
108409467b48Spatrick     if (MatchingInlineAsm) {
108509467b48Spatrick       if (!getLexer().isAtStartOfStatement())
108609467b48Spatrick         Parser.eatToEndOfStatement();
108709467b48Spatrick       return false;
108809467b48Spatrick     }
108909467b48Spatrick     return Parser.Error(L, Msg, Range);
109009467b48Spatrick   }
109109467b48Spatrick 
1092*d415bd75Srobert   bool MatchRegisterByName(MCRegister &RegNo, StringRef RegName, SMLoc StartLoc,
1093097a140dSpatrick                            SMLoc EndLoc);
1094*d415bd75Srobert   bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1095097a140dSpatrick                      bool RestoreOnFailure);
1096097a140dSpatrick 
109709467b48Spatrick   std::unique_ptr<X86Operand> DefaultMemSIOperand(SMLoc Loc);
109809467b48Spatrick   std::unique_ptr<X86Operand> DefaultMemDIOperand(SMLoc Loc);
109909467b48Spatrick   bool IsSIReg(unsigned Reg);
110009467b48Spatrick   unsigned GetSIDIForRegClass(unsigned RegClassID, unsigned Reg, bool IsSIReg);
110109467b48Spatrick   void
110209467b48Spatrick   AddDefaultSrcDestOperands(OperandVector &Operands,
110309467b48Spatrick                             std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
110409467b48Spatrick                             std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
110509467b48Spatrick   bool VerifyAndAdjustOperands(OperandVector &OrigOperands,
110609467b48Spatrick                                OperandVector &FinalOperands);
1107*d415bd75Srobert   bool parseOperand(OperandVector &Operands, StringRef Name);
1108*d415bd75Srobert   bool parseATTOperand(OperandVector &Operands);
1109*d415bd75Srobert   bool parseIntelOperand(OperandVector &Operands, StringRef Name);
111009467b48Spatrick   bool ParseIntelOffsetOperator(const MCExpr *&Val, StringRef &ID,
111109467b48Spatrick                                 InlineAsmIdentifierInfo &Info, SMLoc &End);
111209467b48Spatrick   bool ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End);
111309467b48Spatrick   unsigned IdentifyIntelInlineAsmOperator(StringRef Name);
111409467b48Spatrick   unsigned ParseIntelInlineAsmOperator(unsigned OpKind);
111573471bf0Spatrick   unsigned IdentifyMasmOperator(StringRef Name);
111673471bf0Spatrick   bool ParseMasmOperator(unsigned OpKind, int64_t &Val);
111773471bf0Spatrick   bool ParseRoundingModeOp(SMLoc Start, OperandVector &Operands);
111809467b48Spatrick   bool ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM,
111909467b48Spatrick                                bool &ParseError, SMLoc &End);
112073471bf0Spatrick   bool ParseMasmNamedOperator(StringRef Name, IntelExprStateMachine &SM,
112173471bf0Spatrick                               bool &ParseError, SMLoc &End);
112209467b48Spatrick   void RewriteIntelExpression(IntelExprStateMachine &SM, SMLoc Start,
112309467b48Spatrick                               SMLoc End);
112409467b48Spatrick   bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
112509467b48Spatrick   bool ParseIntelInlineAsmIdentifier(const MCExpr *&Val, StringRef &Identifier,
112609467b48Spatrick                                      InlineAsmIdentifierInfo &Info,
112709467b48Spatrick                                      bool IsUnevaluatedOperand, SMLoc &End,
112809467b48Spatrick                                      bool IsParsingOffsetOperator = false);
1129*d415bd75Srobert   void tryParseOperandIdx(AsmToken::TokenKind PrevTK,
1130*d415bd75Srobert                           IntelExprStateMachine &SM);
113109467b48Spatrick 
113273471bf0Spatrick   bool ParseMemOperand(unsigned SegReg, const MCExpr *Disp, SMLoc StartLoc,
113373471bf0Spatrick                        SMLoc EndLoc, OperandVector &Operands);
113409467b48Spatrick 
113509467b48Spatrick   X86::CondCode ParseConditionCode(StringRef CCode);
113609467b48Spatrick 
113709467b48Spatrick   bool ParseIntelMemoryOperandSize(unsigned &Size);
113873471bf0Spatrick   bool CreateMemForMSInlineAsm(unsigned SegReg, const MCExpr *Disp,
113973471bf0Spatrick                                unsigned BaseReg, unsigned IndexReg,
114073471bf0Spatrick                                unsigned Scale, SMLoc Start, SMLoc End,
114173471bf0Spatrick                                unsigned Size, StringRef Identifier,
114273471bf0Spatrick                                const InlineAsmIdentifierInfo &Info,
114373471bf0Spatrick                                OperandVector &Operands);
114409467b48Spatrick 
114573471bf0Spatrick   bool parseDirectiveArch();
114673471bf0Spatrick   bool parseDirectiveNops(SMLoc L);
114709467b48Spatrick   bool parseDirectiveEven(SMLoc L);
114809467b48Spatrick   bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
114909467b48Spatrick 
115009467b48Spatrick   /// CodeView FPO data directives.
115109467b48Spatrick   bool parseDirectiveFPOProc(SMLoc L);
115209467b48Spatrick   bool parseDirectiveFPOSetFrame(SMLoc L);
115309467b48Spatrick   bool parseDirectiveFPOPushReg(SMLoc L);
115409467b48Spatrick   bool parseDirectiveFPOStackAlloc(SMLoc L);
115509467b48Spatrick   bool parseDirectiveFPOStackAlign(SMLoc L);
115609467b48Spatrick   bool parseDirectiveFPOEndPrologue(SMLoc L);
115709467b48Spatrick   bool parseDirectiveFPOEndProc(SMLoc L);
115809467b48Spatrick 
115909467b48Spatrick   /// SEH directives.
1160*d415bd75Srobert   bool parseSEHRegisterNumber(unsigned RegClassID, MCRegister &RegNo);
116109467b48Spatrick   bool parseDirectiveSEHPushReg(SMLoc);
116209467b48Spatrick   bool parseDirectiveSEHSetFrame(SMLoc);
116309467b48Spatrick   bool parseDirectiveSEHSaveReg(SMLoc);
116409467b48Spatrick   bool parseDirectiveSEHSaveXMM(SMLoc);
116509467b48Spatrick   bool parseDirectiveSEHPushFrame(SMLoc);
116609467b48Spatrick 
116709467b48Spatrick   unsigned checkTargetMatchPredicate(MCInst &Inst) override;
116809467b48Spatrick 
116909467b48Spatrick   bool validateInstruction(MCInst &Inst, const OperandVector &Ops);
117009467b48Spatrick   bool processInstruction(MCInst &Inst, const OperandVector &Ops);
117109467b48Spatrick 
1172097a140dSpatrick   // Load Value Injection (LVI) Mitigations for machine code
1173097a140dSpatrick   void emitWarningForSpecialLVIInstruction(SMLoc Loc);
1174097a140dSpatrick   void applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out);
1175097a140dSpatrick   void applyLVILoadHardeningMitigation(MCInst &Inst, MCStreamer &Out);
1176097a140dSpatrick 
1177097a140dSpatrick   /// Wrapper around MCStreamer::emitInstruction(). Possibly adds
117809467b48Spatrick   /// instrumentation around Inst.
1179097a140dSpatrick   void emitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out);
118009467b48Spatrick 
118109467b48Spatrick   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
118209467b48Spatrick                                OperandVector &Operands, MCStreamer &Out,
118309467b48Spatrick                                uint64_t &ErrorInfo,
118409467b48Spatrick                                bool MatchingInlineAsm) override;
118509467b48Spatrick 
118609467b48Spatrick   void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, OperandVector &Operands,
118709467b48Spatrick                          MCStreamer &Out, bool MatchingInlineAsm);
118809467b48Spatrick 
118909467b48Spatrick   bool ErrorMissingFeature(SMLoc IDLoc, const FeatureBitset &MissingFeatures,
119009467b48Spatrick                            bool MatchingInlineAsm);
119109467b48Spatrick 
119209467b48Spatrick   bool MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
119309467b48Spatrick                                   OperandVector &Operands, MCStreamer &Out,
119409467b48Spatrick                                   uint64_t &ErrorInfo,
119509467b48Spatrick                                   bool MatchingInlineAsm);
119609467b48Spatrick 
119709467b48Spatrick   bool MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
119809467b48Spatrick                                     OperandVector &Operands, MCStreamer &Out,
119909467b48Spatrick                                     uint64_t &ErrorInfo,
120009467b48Spatrick                                     bool MatchingInlineAsm);
120109467b48Spatrick 
120209467b48Spatrick   bool OmitRegisterFromClobberLists(unsigned RegNo) override;
120309467b48Spatrick 
120409467b48Spatrick   /// Parses AVX512 specific operand primitives: masked registers ({%k<NUM>}, {z})
120509467b48Spatrick   /// and memory broadcasting ({1to<NUM>}) primitives, updating Operands vector if required.
120609467b48Spatrick   /// return false if no parsing errors occurred, true otherwise.
120773471bf0Spatrick   bool HandleAVX512Operand(OperandVector &Operands);
120809467b48Spatrick 
120909467b48Spatrick   bool ParseZ(std::unique_ptr<X86Operand> &Z, const SMLoc &StartLoc);
121009467b48Spatrick 
is64BitMode() const121109467b48Spatrick   bool is64BitMode() const {
121209467b48Spatrick     // FIXME: Can tablegen auto-generate this?
1213*d415bd75Srobert     return getSTI().getFeatureBits()[X86::Is64Bit];
121409467b48Spatrick   }
is32BitMode() const121509467b48Spatrick   bool is32BitMode() const {
121609467b48Spatrick     // FIXME: Can tablegen auto-generate this?
1217*d415bd75Srobert     return getSTI().getFeatureBits()[X86::Is32Bit];
121809467b48Spatrick   }
is16BitMode() const121909467b48Spatrick   bool is16BitMode() const {
122009467b48Spatrick     // FIXME: Can tablegen auto-generate this?
1221*d415bd75Srobert     return getSTI().getFeatureBits()[X86::Is16Bit];
122209467b48Spatrick   }
SwitchMode(unsigned mode)122309467b48Spatrick   void SwitchMode(unsigned mode) {
122409467b48Spatrick     MCSubtargetInfo &STI = copySTI();
1225*d415bd75Srobert     FeatureBitset AllModes({X86::Is64Bit, X86::Is32Bit, X86::Is16Bit});
122609467b48Spatrick     FeatureBitset OldMode = STI.getFeatureBits() & AllModes;
122709467b48Spatrick     FeatureBitset FB = ComputeAvailableFeatures(
122809467b48Spatrick       STI.ToggleFeature(OldMode.flip(mode)));
122909467b48Spatrick     setAvailableFeatures(FB);
123009467b48Spatrick 
123109467b48Spatrick     assert(FeatureBitset({mode}) == (STI.getFeatureBits() & AllModes));
123209467b48Spatrick   }
123309467b48Spatrick 
getPointerWidth()123409467b48Spatrick   unsigned getPointerWidth() {
123509467b48Spatrick     if (is16BitMode()) return 16;
123609467b48Spatrick     if (is32BitMode()) return 32;
123709467b48Spatrick     if (is64BitMode()) return 64;
123809467b48Spatrick     llvm_unreachable("invalid mode");
123909467b48Spatrick   }
124009467b48Spatrick 
isParsingIntelSyntax()124109467b48Spatrick   bool isParsingIntelSyntax() {
124209467b48Spatrick     return getParser().getAssemblerDialect();
124309467b48Spatrick   }
124409467b48Spatrick 
124509467b48Spatrick   /// @name Auto-generated Matcher Functions
124609467b48Spatrick   /// {
124709467b48Spatrick 
124809467b48Spatrick #define GET_ASSEMBLER_HEADER
124909467b48Spatrick #include "X86GenAsmMatcher.inc"
125009467b48Spatrick 
125109467b48Spatrick   /// }
125209467b48Spatrick 
125309467b48Spatrick public:
125409467b48Spatrick   enum X86MatchResultTy {
125509467b48Spatrick     Match_Unsupported = FIRST_TARGET_MATCH_RESULT_TY,
125609467b48Spatrick #define GET_OPERAND_DIAGNOSTIC_TYPES
125709467b48Spatrick #include "X86GenAsmMatcher.inc"
125809467b48Spatrick   };
125909467b48Spatrick 
X86AsmParser(const MCSubtargetInfo & sti,MCAsmParser & Parser,const MCInstrInfo & mii,const MCTargetOptions & Options)126009467b48Spatrick   X86AsmParser(const MCSubtargetInfo &sti, MCAsmParser &Parser,
126109467b48Spatrick                const MCInstrInfo &mii, const MCTargetOptions &Options)
126209467b48Spatrick       : MCTargetAsmParser(Options, sti, mii),  InstInfo(nullptr),
126309467b48Spatrick         Code16GCC(false) {
126409467b48Spatrick 
126509467b48Spatrick     Parser.addAliasForDirective(".word", ".2byte");
126609467b48Spatrick 
126709467b48Spatrick     // Initialize the set of available features.
126809467b48Spatrick     setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
126909467b48Spatrick   }
127009467b48Spatrick 
1271*d415bd75Srobert   bool parseRegister(MCRegister &RegNo, SMLoc &StartLoc,
1272*d415bd75Srobert                      SMLoc &EndLoc) override;
1273*d415bd75Srobert   OperandMatchResultTy tryParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
1274097a140dSpatrick                                         SMLoc &EndLoc) override;
127509467b48Spatrick 
127609467b48Spatrick   bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) override;
127709467b48Spatrick 
127809467b48Spatrick   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
127909467b48Spatrick                         SMLoc NameLoc, OperandVector &Operands) override;
128009467b48Spatrick 
128109467b48Spatrick   bool ParseDirective(AsmToken DirectiveID) override;
128209467b48Spatrick };
128309467b48Spatrick } // end anonymous namespace
128409467b48Spatrick 
128509467b48Spatrick /// @name Auto-generated Match Functions
128609467b48Spatrick /// {
128709467b48Spatrick 
128809467b48Spatrick static unsigned MatchRegisterName(StringRef Name);
128909467b48Spatrick 
129009467b48Spatrick /// }
129109467b48Spatrick 
CheckBaseRegAndIndexRegAndScale(unsigned BaseReg,unsigned IndexReg,unsigned Scale,bool Is64BitMode,StringRef & ErrMsg)129209467b48Spatrick static bool CheckBaseRegAndIndexRegAndScale(unsigned BaseReg, unsigned IndexReg,
129309467b48Spatrick                                             unsigned Scale, bool Is64BitMode,
129409467b48Spatrick                                             StringRef &ErrMsg) {
129509467b48Spatrick   // If we have both a base register and an index register make sure they are
129609467b48Spatrick   // both 64-bit or 32-bit registers.
129709467b48Spatrick   // To support VSIB, IndexReg can be 128-bit or 256-bit registers.
129809467b48Spatrick 
129909467b48Spatrick   if (BaseReg != 0 &&
130009467b48Spatrick       !(BaseReg == X86::RIP || BaseReg == X86::EIP ||
130109467b48Spatrick         X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) ||
130209467b48Spatrick         X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) ||
130309467b48Spatrick         X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg))) {
130409467b48Spatrick     ErrMsg = "invalid base+index expression";
130509467b48Spatrick     return true;
130609467b48Spatrick   }
130709467b48Spatrick 
130809467b48Spatrick   if (IndexReg != 0 &&
130909467b48Spatrick       !(IndexReg == X86::EIZ || IndexReg == X86::RIZ ||
131009467b48Spatrick         X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
131109467b48Spatrick         X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
131209467b48Spatrick         X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg) ||
131309467b48Spatrick         X86MCRegisterClasses[X86::VR128XRegClassID].contains(IndexReg) ||
131409467b48Spatrick         X86MCRegisterClasses[X86::VR256XRegClassID].contains(IndexReg) ||
131509467b48Spatrick         X86MCRegisterClasses[X86::VR512RegClassID].contains(IndexReg))) {
131609467b48Spatrick     ErrMsg = "invalid base+index expression";
131709467b48Spatrick     return true;
131809467b48Spatrick   }
131909467b48Spatrick 
132009467b48Spatrick   if (((BaseReg == X86::RIP || BaseReg == X86::EIP) && IndexReg != 0) ||
132109467b48Spatrick       IndexReg == X86::EIP || IndexReg == X86::RIP ||
132209467b48Spatrick       IndexReg == X86::ESP || IndexReg == X86::RSP) {
132309467b48Spatrick     ErrMsg = "invalid base+index expression";
132409467b48Spatrick     return true;
132509467b48Spatrick   }
132609467b48Spatrick 
132709467b48Spatrick   // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed,
132809467b48Spatrick   // and then only in non-64-bit modes.
132909467b48Spatrick   if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
133009467b48Spatrick       (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP &&
133109467b48Spatrick                        BaseReg != X86::SI && BaseReg != X86::DI))) {
133209467b48Spatrick     ErrMsg = "invalid 16-bit base register";
133309467b48Spatrick     return true;
133409467b48Spatrick   }
133509467b48Spatrick 
133609467b48Spatrick   if (BaseReg == 0 &&
133709467b48Spatrick       X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {
133809467b48Spatrick     ErrMsg = "16-bit memory operand may not include only index register";
133909467b48Spatrick     return true;
134009467b48Spatrick   }
134109467b48Spatrick 
134209467b48Spatrick   if (BaseReg != 0 && IndexReg != 0) {
134309467b48Spatrick     if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&
134409467b48Spatrick         (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
134509467b48Spatrick          X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
134609467b48Spatrick          IndexReg == X86::EIZ)) {
134709467b48Spatrick       ErrMsg = "base register is 64-bit, but index register is not";
134809467b48Spatrick       return true;
134909467b48Spatrick     }
135009467b48Spatrick     if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) &&
135109467b48Spatrick         (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
135209467b48Spatrick          X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg) ||
135309467b48Spatrick          IndexReg == X86::RIZ)) {
135409467b48Spatrick       ErrMsg = "base register is 32-bit, but index register is not";
135509467b48Spatrick       return true;
135609467b48Spatrick     }
135709467b48Spatrick     if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) {
135809467b48Spatrick       if (X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
135909467b48Spatrick           X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) {
136009467b48Spatrick         ErrMsg = "base register is 16-bit, but index register is not";
136109467b48Spatrick         return true;
136209467b48Spatrick       }
136309467b48Spatrick       if ((BaseReg != X86::BX && BaseReg != X86::BP) ||
136409467b48Spatrick           (IndexReg != X86::SI && IndexReg != X86::DI)) {
136509467b48Spatrick         ErrMsg = "invalid 16-bit base/index register combination";
136609467b48Spatrick         return true;
136709467b48Spatrick       }
136809467b48Spatrick     }
136909467b48Spatrick   }
137009467b48Spatrick 
137109467b48Spatrick   // RIP/EIP-relative addressing is only supported in 64-bit mode.
137209467b48Spatrick   if (!Is64BitMode && BaseReg != 0 &&
137309467b48Spatrick       (BaseReg == X86::RIP || BaseReg == X86::EIP)) {
137409467b48Spatrick     ErrMsg = "IP-relative addressing requires 64-bit mode";
137509467b48Spatrick     return true;
137609467b48Spatrick   }
137709467b48Spatrick 
137809467b48Spatrick   return checkScale(Scale, ErrMsg);
137909467b48Spatrick }
138009467b48Spatrick 
MatchRegisterByName(MCRegister & RegNo,StringRef RegName,SMLoc StartLoc,SMLoc EndLoc)1381*d415bd75Srobert bool X86AsmParser::MatchRegisterByName(MCRegister &RegNo, StringRef RegName,
1382097a140dSpatrick                                        SMLoc StartLoc, SMLoc EndLoc) {
138309467b48Spatrick   // If we encounter a %, ignore it. This code handles registers with and
138409467b48Spatrick   // without the prefix, unprefixed registers can occur in cfi directives.
1385097a140dSpatrick   RegName.consume_front("%");
138609467b48Spatrick 
1387097a140dSpatrick   RegNo = MatchRegisterName(RegName);
138809467b48Spatrick 
138909467b48Spatrick   // If the match failed, try the register name as lowercase.
139009467b48Spatrick   if (RegNo == 0)
1391097a140dSpatrick     RegNo = MatchRegisterName(RegName.lower());
139209467b48Spatrick 
139309467b48Spatrick   // The "flags" and "mxcsr" registers cannot be referenced directly.
139409467b48Spatrick   // Treat it as an identifier instead.
1395097a140dSpatrick   if (isParsingMSInlineAsm() && isParsingIntelSyntax() &&
139609467b48Spatrick       (RegNo == X86::EFLAGS || RegNo == X86::MXCSR))
139709467b48Spatrick     RegNo = 0;
139809467b48Spatrick 
139909467b48Spatrick   if (!is64BitMode()) {
140009467b48Spatrick     // FIXME: This should be done using Requires<Not64BitMode> and
140109467b48Spatrick     // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also
140209467b48Spatrick     // checked.
140309467b48Spatrick     if (RegNo == X86::RIZ || RegNo == X86::RIP ||
140409467b48Spatrick         X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||
140509467b48Spatrick         X86II::isX86_64NonExtLowByteReg(RegNo) ||
140609467b48Spatrick         X86II::isX86_64ExtendedReg(RegNo)) {
140709467b48Spatrick       return Error(StartLoc,
140809467b48Spatrick                    "register %" + RegName + " is only available in 64-bit mode",
140909467b48Spatrick                    SMRange(StartLoc, EndLoc));
141009467b48Spatrick     }
141109467b48Spatrick   }
141209467b48Spatrick 
1413097a140dSpatrick   // If this is "db[0-15]", match it as an alias
1414097a140dSpatrick   // for dr[0-15].
1415097a140dSpatrick   if (RegNo == 0 && RegName.startswith("db")) {
1416097a140dSpatrick     if (RegName.size() == 3) {
1417097a140dSpatrick       switch (RegName[2]) {
1418097a140dSpatrick       case '0':
1419097a140dSpatrick         RegNo = X86::DR0;
1420097a140dSpatrick         break;
1421097a140dSpatrick       case '1':
1422097a140dSpatrick         RegNo = X86::DR1;
1423097a140dSpatrick         break;
1424097a140dSpatrick       case '2':
1425097a140dSpatrick         RegNo = X86::DR2;
1426097a140dSpatrick         break;
1427097a140dSpatrick       case '3':
1428097a140dSpatrick         RegNo = X86::DR3;
1429097a140dSpatrick         break;
1430097a140dSpatrick       case '4':
1431097a140dSpatrick         RegNo = X86::DR4;
1432097a140dSpatrick         break;
1433097a140dSpatrick       case '5':
1434097a140dSpatrick         RegNo = X86::DR5;
1435097a140dSpatrick         break;
1436097a140dSpatrick       case '6':
1437097a140dSpatrick         RegNo = X86::DR6;
1438097a140dSpatrick         break;
1439097a140dSpatrick       case '7':
1440097a140dSpatrick         RegNo = X86::DR7;
1441097a140dSpatrick         break;
1442097a140dSpatrick       case '8':
1443097a140dSpatrick         RegNo = X86::DR8;
1444097a140dSpatrick         break;
1445097a140dSpatrick       case '9':
1446097a140dSpatrick         RegNo = X86::DR9;
1447097a140dSpatrick         break;
1448097a140dSpatrick       }
1449097a140dSpatrick     } else if (RegName.size() == 4 && RegName[2] == '1') {
1450097a140dSpatrick       switch (RegName[3]) {
1451097a140dSpatrick       case '0':
1452097a140dSpatrick         RegNo = X86::DR10;
1453097a140dSpatrick         break;
1454097a140dSpatrick       case '1':
1455097a140dSpatrick         RegNo = X86::DR11;
1456097a140dSpatrick         break;
1457097a140dSpatrick       case '2':
1458097a140dSpatrick         RegNo = X86::DR12;
1459097a140dSpatrick         break;
1460097a140dSpatrick       case '3':
1461097a140dSpatrick         RegNo = X86::DR13;
1462097a140dSpatrick         break;
1463097a140dSpatrick       case '4':
1464097a140dSpatrick         RegNo = X86::DR14;
1465097a140dSpatrick         break;
1466097a140dSpatrick       case '5':
1467097a140dSpatrick         RegNo = X86::DR15;
1468097a140dSpatrick         break;
1469097a140dSpatrick       }
1470097a140dSpatrick     }
1471097a140dSpatrick   }
1472097a140dSpatrick 
1473097a140dSpatrick   if (RegNo == 0) {
1474097a140dSpatrick     if (isParsingIntelSyntax())
1475097a140dSpatrick       return true;
1476097a140dSpatrick     return Error(StartLoc, "invalid register name", SMRange(StartLoc, EndLoc));
1477097a140dSpatrick   }
1478097a140dSpatrick   return false;
1479097a140dSpatrick }
1480097a140dSpatrick 
ParseRegister(MCRegister & RegNo,SMLoc & StartLoc,SMLoc & EndLoc,bool RestoreOnFailure)1481*d415bd75Srobert bool X86AsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
1482097a140dSpatrick                                  SMLoc &EndLoc, bool RestoreOnFailure) {
1483097a140dSpatrick   MCAsmParser &Parser = getParser();
1484097a140dSpatrick   MCAsmLexer &Lexer = getLexer();
1485097a140dSpatrick   RegNo = 0;
1486097a140dSpatrick 
1487097a140dSpatrick   SmallVector<AsmToken, 5> Tokens;
1488097a140dSpatrick   auto OnFailure = [RestoreOnFailure, &Lexer, &Tokens]() {
1489097a140dSpatrick     if (RestoreOnFailure) {
1490097a140dSpatrick       while (!Tokens.empty()) {
1491097a140dSpatrick         Lexer.UnLex(Tokens.pop_back_val());
1492097a140dSpatrick       }
1493097a140dSpatrick     }
1494097a140dSpatrick   };
1495097a140dSpatrick 
1496097a140dSpatrick   const AsmToken &PercentTok = Parser.getTok();
1497097a140dSpatrick   StartLoc = PercentTok.getLoc();
1498097a140dSpatrick 
1499097a140dSpatrick   // If we encounter a %, ignore it. This code handles registers with and
1500097a140dSpatrick   // without the prefix, unprefixed registers can occur in cfi directives.
1501097a140dSpatrick   if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent)) {
1502097a140dSpatrick     Tokens.push_back(PercentTok);
1503097a140dSpatrick     Parser.Lex(); // Eat percent token.
1504097a140dSpatrick   }
1505097a140dSpatrick 
1506097a140dSpatrick   const AsmToken &Tok = Parser.getTok();
1507097a140dSpatrick   EndLoc = Tok.getEndLoc();
1508097a140dSpatrick 
1509097a140dSpatrick   if (Tok.isNot(AsmToken::Identifier)) {
1510097a140dSpatrick     OnFailure();
1511097a140dSpatrick     if (isParsingIntelSyntax()) return true;
1512097a140dSpatrick     return Error(StartLoc, "invalid register name",
1513097a140dSpatrick                  SMRange(StartLoc, EndLoc));
1514097a140dSpatrick   }
1515097a140dSpatrick 
1516097a140dSpatrick   if (MatchRegisterByName(RegNo, Tok.getString(), StartLoc, EndLoc)) {
1517097a140dSpatrick     OnFailure();
1518097a140dSpatrick     return true;
1519097a140dSpatrick   }
1520097a140dSpatrick 
152109467b48Spatrick   // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
152209467b48Spatrick   if (RegNo == X86::ST0) {
1523097a140dSpatrick     Tokens.push_back(Tok);
152409467b48Spatrick     Parser.Lex(); // Eat 'st'
152509467b48Spatrick 
152609467b48Spatrick     // Check to see if we have '(4)' after %st.
1527097a140dSpatrick     if (Lexer.isNot(AsmToken::LParen))
152809467b48Spatrick       return false;
152909467b48Spatrick     // Lex the paren.
1530097a140dSpatrick     Tokens.push_back(Parser.getTok());
1531097a140dSpatrick     Parser.Lex();
153209467b48Spatrick 
153309467b48Spatrick     const AsmToken &IntTok = Parser.getTok();
1534097a140dSpatrick     if (IntTok.isNot(AsmToken::Integer)) {
1535097a140dSpatrick       OnFailure();
153609467b48Spatrick       return Error(IntTok.getLoc(), "expected stack index");
1537097a140dSpatrick     }
153809467b48Spatrick     switch (IntTok.getIntVal()) {
153909467b48Spatrick     case 0: RegNo = X86::ST0; break;
154009467b48Spatrick     case 1: RegNo = X86::ST1; break;
154109467b48Spatrick     case 2: RegNo = X86::ST2; break;
154209467b48Spatrick     case 3: RegNo = X86::ST3; break;
154309467b48Spatrick     case 4: RegNo = X86::ST4; break;
154409467b48Spatrick     case 5: RegNo = X86::ST5; break;
154509467b48Spatrick     case 6: RegNo = X86::ST6; break;
154609467b48Spatrick     case 7: RegNo = X86::ST7; break;
1547097a140dSpatrick     default:
1548097a140dSpatrick       OnFailure();
1549097a140dSpatrick       return Error(IntTok.getLoc(), "invalid stack index");
155009467b48Spatrick     }
155109467b48Spatrick 
1552097a140dSpatrick     // Lex IntTok
1553097a140dSpatrick     Tokens.push_back(IntTok);
1554097a140dSpatrick     Parser.Lex();
1555097a140dSpatrick     if (Lexer.isNot(AsmToken::RParen)) {
1556097a140dSpatrick       OnFailure();
155709467b48Spatrick       return Error(Parser.getTok().getLoc(), "expected ')'");
1558097a140dSpatrick     }
155909467b48Spatrick 
156009467b48Spatrick     EndLoc = Parser.getTok().getEndLoc();
156109467b48Spatrick     Parser.Lex(); // Eat ')'
156209467b48Spatrick     return false;
156309467b48Spatrick   }
156409467b48Spatrick 
156509467b48Spatrick   EndLoc = Parser.getTok().getEndLoc();
156609467b48Spatrick 
156709467b48Spatrick   if (RegNo == 0) {
1568097a140dSpatrick     OnFailure();
156909467b48Spatrick     if (isParsingIntelSyntax()) return true;
157009467b48Spatrick     return Error(StartLoc, "invalid register name",
157109467b48Spatrick                  SMRange(StartLoc, EndLoc));
157209467b48Spatrick   }
157309467b48Spatrick 
157409467b48Spatrick   Parser.Lex(); // Eat identifier token.
157509467b48Spatrick   return false;
157609467b48Spatrick }
157709467b48Spatrick 
parseRegister(MCRegister & RegNo,SMLoc & StartLoc,SMLoc & EndLoc)1578*d415bd75Srobert bool X86AsmParser::parseRegister(MCRegister &RegNo, SMLoc &StartLoc,
1579097a140dSpatrick                                  SMLoc &EndLoc) {
1580097a140dSpatrick   return ParseRegister(RegNo, StartLoc, EndLoc, /*RestoreOnFailure=*/false);
1581097a140dSpatrick }
1582097a140dSpatrick 
tryParseRegister(MCRegister & RegNo,SMLoc & StartLoc,SMLoc & EndLoc)1583*d415bd75Srobert OperandMatchResultTy X86AsmParser::tryParseRegister(MCRegister &RegNo,
1584097a140dSpatrick                                                     SMLoc &StartLoc,
1585097a140dSpatrick                                                     SMLoc &EndLoc) {
1586097a140dSpatrick   bool Result =
1587097a140dSpatrick       ParseRegister(RegNo, StartLoc, EndLoc, /*RestoreOnFailure=*/true);
1588097a140dSpatrick   bool PendingErrors = getParser().hasPendingError();
1589097a140dSpatrick   getParser().clearPendingErrors();
1590097a140dSpatrick   if (PendingErrors)
1591097a140dSpatrick     return MatchOperand_ParseFail;
1592097a140dSpatrick   if (Result)
1593097a140dSpatrick     return MatchOperand_NoMatch;
1594097a140dSpatrick   return MatchOperand_Success;
1595097a140dSpatrick }
1596097a140dSpatrick 
DefaultMemSIOperand(SMLoc Loc)159709467b48Spatrick std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
159809467b48Spatrick   bool Parse32 = is32BitMode() || Code16GCC;
159909467b48Spatrick   unsigned Basereg = is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
160009467b48Spatrick   const MCExpr *Disp = MCConstantExpr::create(0, getContext());
160109467b48Spatrick   return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
160209467b48Spatrick                                /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1,
160309467b48Spatrick                                Loc, Loc, 0);
160409467b48Spatrick }
160509467b48Spatrick 
DefaultMemDIOperand(SMLoc Loc)160609467b48Spatrick std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
160709467b48Spatrick   bool Parse32 = is32BitMode() || Code16GCC;
160809467b48Spatrick   unsigned Basereg = is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
160909467b48Spatrick   const MCExpr *Disp = MCConstantExpr::create(0, getContext());
161009467b48Spatrick   return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
161109467b48Spatrick                                /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1,
161209467b48Spatrick                                Loc, Loc, 0);
161309467b48Spatrick }
161409467b48Spatrick 
IsSIReg(unsigned Reg)161509467b48Spatrick bool X86AsmParser::IsSIReg(unsigned Reg) {
161609467b48Spatrick   switch (Reg) {
161709467b48Spatrick   default: llvm_unreachable("Only (R|E)SI and (R|E)DI are expected!");
161809467b48Spatrick   case X86::RSI:
161909467b48Spatrick   case X86::ESI:
162009467b48Spatrick   case X86::SI:
162109467b48Spatrick     return true;
162209467b48Spatrick   case X86::RDI:
162309467b48Spatrick   case X86::EDI:
162409467b48Spatrick   case X86::DI:
162509467b48Spatrick     return false;
162609467b48Spatrick   }
162709467b48Spatrick }
162809467b48Spatrick 
GetSIDIForRegClass(unsigned RegClassID,unsigned Reg,bool IsSIReg)162909467b48Spatrick unsigned X86AsmParser::GetSIDIForRegClass(unsigned RegClassID, unsigned Reg,
163009467b48Spatrick                                           bool IsSIReg) {
163109467b48Spatrick   switch (RegClassID) {
163209467b48Spatrick   default: llvm_unreachable("Unexpected register class");
163309467b48Spatrick   case X86::GR64RegClassID:
163409467b48Spatrick     return IsSIReg ? X86::RSI : X86::RDI;
163509467b48Spatrick   case X86::GR32RegClassID:
163609467b48Spatrick     return IsSIReg ? X86::ESI : X86::EDI;
163709467b48Spatrick   case X86::GR16RegClassID:
163809467b48Spatrick     return IsSIReg ? X86::SI : X86::DI;
163909467b48Spatrick   }
164009467b48Spatrick }
164109467b48Spatrick 
AddDefaultSrcDestOperands(OperandVector & Operands,std::unique_ptr<llvm::MCParsedAsmOperand> && Src,std::unique_ptr<llvm::MCParsedAsmOperand> && Dst)164209467b48Spatrick void X86AsmParser::AddDefaultSrcDestOperands(
164309467b48Spatrick     OperandVector& Operands, std::unique_ptr<llvm::MCParsedAsmOperand> &&Src,
164409467b48Spatrick     std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst) {
164509467b48Spatrick   if (isParsingIntelSyntax()) {
164609467b48Spatrick     Operands.push_back(std::move(Dst));
164709467b48Spatrick     Operands.push_back(std::move(Src));
164809467b48Spatrick   }
164909467b48Spatrick   else {
165009467b48Spatrick     Operands.push_back(std::move(Src));
165109467b48Spatrick     Operands.push_back(std::move(Dst));
165209467b48Spatrick   }
165309467b48Spatrick }
165409467b48Spatrick 
VerifyAndAdjustOperands(OperandVector & OrigOperands,OperandVector & FinalOperands)165509467b48Spatrick bool X86AsmParser::VerifyAndAdjustOperands(OperandVector &OrigOperands,
165609467b48Spatrick                                            OperandVector &FinalOperands) {
165709467b48Spatrick 
165809467b48Spatrick   if (OrigOperands.size() > 1) {
165909467b48Spatrick     // Check if sizes match, OrigOperands also contains the instruction name
166009467b48Spatrick     assert(OrigOperands.size() == FinalOperands.size() + 1 &&
166109467b48Spatrick            "Operand size mismatch");
166209467b48Spatrick 
166309467b48Spatrick     SmallVector<std::pair<SMLoc, std::string>, 2> Warnings;
166409467b48Spatrick     // Verify types match
166509467b48Spatrick     int RegClassID = -1;
166609467b48Spatrick     for (unsigned int i = 0; i < FinalOperands.size(); ++i) {
166709467b48Spatrick       X86Operand &OrigOp = static_cast<X86Operand &>(*OrigOperands[i + 1]);
166809467b48Spatrick       X86Operand &FinalOp = static_cast<X86Operand &>(*FinalOperands[i]);
166909467b48Spatrick 
167009467b48Spatrick       if (FinalOp.isReg() &&
167109467b48Spatrick           (!OrigOp.isReg() || FinalOp.getReg() != OrigOp.getReg()))
167209467b48Spatrick         // Return false and let a normal complaint about bogus operands happen
167309467b48Spatrick         return false;
167409467b48Spatrick 
167509467b48Spatrick       if (FinalOp.isMem()) {
167609467b48Spatrick 
167709467b48Spatrick         if (!OrigOp.isMem())
167809467b48Spatrick           // Return false and let a normal complaint about bogus operands happen
167909467b48Spatrick           return false;
168009467b48Spatrick 
168109467b48Spatrick         unsigned OrigReg = OrigOp.Mem.BaseReg;
168209467b48Spatrick         unsigned FinalReg = FinalOp.Mem.BaseReg;
168309467b48Spatrick 
168409467b48Spatrick         // If we've already encounterd a register class, make sure all register
168509467b48Spatrick         // bases are of the same register class
168609467b48Spatrick         if (RegClassID != -1 &&
168709467b48Spatrick             !X86MCRegisterClasses[RegClassID].contains(OrigReg)) {
168809467b48Spatrick           return Error(OrigOp.getStartLoc(),
168909467b48Spatrick                        "mismatching source and destination index registers");
169009467b48Spatrick         }
169109467b48Spatrick 
169209467b48Spatrick         if (X86MCRegisterClasses[X86::GR64RegClassID].contains(OrigReg))
169309467b48Spatrick           RegClassID = X86::GR64RegClassID;
169409467b48Spatrick         else if (X86MCRegisterClasses[X86::GR32RegClassID].contains(OrigReg))
169509467b48Spatrick           RegClassID = X86::GR32RegClassID;
169609467b48Spatrick         else if (X86MCRegisterClasses[X86::GR16RegClassID].contains(OrigReg))
169709467b48Spatrick           RegClassID = X86::GR16RegClassID;
169809467b48Spatrick         else
169909467b48Spatrick           // Unexpected register class type
170009467b48Spatrick           // Return false and let a normal complaint about bogus operands happen
170109467b48Spatrick           return false;
170209467b48Spatrick 
170309467b48Spatrick         bool IsSI = IsSIReg(FinalReg);
170409467b48Spatrick         FinalReg = GetSIDIForRegClass(RegClassID, FinalReg, IsSI);
170509467b48Spatrick 
170609467b48Spatrick         if (FinalReg != OrigReg) {
170709467b48Spatrick           std::string RegName = IsSI ? "ES:(R|E)SI" : "ES:(R|E)DI";
170809467b48Spatrick           Warnings.push_back(std::make_pair(
170909467b48Spatrick               OrigOp.getStartLoc(),
171009467b48Spatrick               "memory operand is only for determining the size, " + RegName +
171109467b48Spatrick                   " will be used for the location"));
171209467b48Spatrick         }
171309467b48Spatrick 
171409467b48Spatrick         FinalOp.Mem.Size = OrigOp.Mem.Size;
171509467b48Spatrick         FinalOp.Mem.SegReg = OrigOp.Mem.SegReg;
171609467b48Spatrick         FinalOp.Mem.BaseReg = FinalReg;
171709467b48Spatrick       }
171809467b48Spatrick     }
171909467b48Spatrick 
172009467b48Spatrick     // Produce warnings only if all the operands passed the adjustment - prevent
172109467b48Spatrick     // legal cases like "movsd (%rax), %xmm0" mistakenly produce warnings
172209467b48Spatrick     for (auto &WarningMsg : Warnings) {
172309467b48Spatrick       Warning(WarningMsg.first, WarningMsg.second);
172409467b48Spatrick     }
172509467b48Spatrick 
172609467b48Spatrick     // Remove old operands
172709467b48Spatrick     for (unsigned int i = 0; i < FinalOperands.size(); ++i)
172809467b48Spatrick       OrigOperands.pop_back();
172909467b48Spatrick   }
173009467b48Spatrick   // OrigOperands.append(FinalOperands.begin(), FinalOperands.end());
173109467b48Spatrick   for (unsigned int i = 0; i < FinalOperands.size(); ++i)
173209467b48Spatrick     OrigOperands.push_back(std::move(FinalOperands[i]));
173309467b48Spatrick 
173409467b48Spatrick   return false;
173509467b48Spatrick }
173609467b48Spatrick 
parseOperand(OperandVector & Operands,StringRef Name)1737*d415bd75Srobert bool X86AsmParser::parseOperand(OperandVector &Operands, StringRef Name) {
173809467b48Spatrick   if (isParsingIntelSyntax())
1739*d415bd75Srobert     return parseIntelOperand(Operands, Name);
174073471bf0Spatrick 
1741*d415bd75Srobert   return parseATTOperand(Operands);
174209467b48Spatrick }
174309467b48Spatrick 
CreateMemForMSInlineAsm(unsigned SegReg,const MCExpr * Disp,unsigned BaseReg,unsigned IndexReg,unsigned Scale,SMLoc Start,SMLoc End,unsigned Size,StringRef Identifier,const InlineAsmIdentifierInfo & Info,OperandVector & Operands)174473471bf0Spatrick bool X86AsmParser::CreateMemForMSInlineAsm(
174509467b48Spatrick     unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg,
174609467b48Spatrick     unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier,
174773471bf0Spatrick     const InlineAsmIdentifierInfo &Info, OperandVector &Operands) {
174809467b48Spatrick   // If we found a decl other than a VarDecl, then assume it is a FuncDecl or
174909467b48Spatrick   // some other label reference.
175009467b48Spatrick   if (Info.isKind(InlineAsmIdentifierInfo::IK_Label)) {
175109467b48Spatrick     // Insert an explicit size if the user didn't have one.
175209467b48Spatrick     if (!Size) {
175309467b48Spatrick       Size = getPointerWidth();
175409467b48Spatrick       InstInfo->AsmRewrites->emplace_back(AOK_SizeDirective, Start,
175509467b48Spatrick                                           /*Len=*/0, Size);
175609467b48Spatrick     }
175709467b48Spatrick     // Create an absolute memory reference in order to match against
175809467b48Spatrick     // instructions taking a PC relative operand.
175973471bf0Spatrick     Operands.push_back(X86Operand::CreateMem(getPointerWidth(), Disp, Start,
176073471bf0Spatrick                                              End, Size, Identifier,
176173471bf0Spatrick                                              Info.Label.Decl));
176273471bf0Spatrick     return false;
176309467b48Spatrick   }
176409467b48Spatrick   // We either have a direct symbol reference, or an offset from a symbol.  The
176509467b48Spatrick   // parser always puts the symbol on the LHS, so look there for size
176609467b48Spatrick   // calculation purposes.
176709467b48Spatrick   unsigned FrontendSize = 0;
176809467b48Spatrick   void *Decl = nullptr;
176909467b48Spatrick   bool IsGlobalLV = false;
177009467b48Spatrick   if (Info.isKind(InlineAsmIdentifierInfo::IK_Var)) {
177109467b48Spatrick     // Size is in terms of bits in this context.
177209467b48Spatrick     FrontendSize = Info.Var.Type * 8;
177309467b48Spatrick     Decl = Info.Var.Decl;
177409467b48Spatrick     IsGlobalLV = Info.Var.IsGlobalLV;
177509467b48Spatrick   }
177609467b48Spatrick   // It is widely common for MS InlineAsm to use a global variable and one/two
177709467b48Spatrick   // registers in a mmory expression, and though unaccessible via rip/eip.
177809467b48Spatrick   if (IsGlobalLV && (BaseReg || IndexReg)) {
1779*d415bd75Srobert     Operands.push_back(X86Operand::CreateMem(getPointerWidth(), Disp, Start,
1780*d415bd75Srobert                                              End, Size, Identifier, Decl, 0,
1781*d415bd75Srobert                                              BaseReg && IndexReg));
178273471bf0Spatrick     return false;
178373471bf0Spatrick   }
178409467b48Spatrick   // Otherwise, we set the base register to a non-zero value
178509467b48Spatrick   // if we don't know the actual value at this time.  This is necessary to
178609467b48Spatrick   // get the matching correct in some cases.
178709467b48Spatrick   BaseReg = BaseReg ? BaseReg : 1;
178873471bf0Spatrick   Operands.push_back(X86Operand::CreateMem(
178973471bf0Spatrick       getPointerWidth(), SegReg, Disp, BaseReg, IndexReg, Scale, Start, End,
179073471bf0Spatrick       Size,
179173471bf0Spatrick       /*DefaultBaseReg=*/X86::RIP, Identifier, Decl, FrontendSize));
179273471bf0Spatrick   return false;
179309467b48Spatrick }
179409467b48Spatrick 
179509467b48Spatrick // Some binary bitwise operators have a named synonymous
179609467b48Spatrick // Query a candidate string for being such a named operator
179709467b48Spatrick // and if so - invoke the appropriate handler
ParseIntelNamedOperator(StringRef Name,IntelExprStateMachine & SM,bool & ParseError,SMLoc & End)179809467b48Spatrick bool X86AsmParser::ParseIntelNamedOperator(StringRef Name,
179909467b48Spatrick                                            IntelExprStateMachine &SM,
180009467b48Spatrick                                            bool &ParseError, SMLoc &End) {
180173471bf0Spatrick   // A named operator should be either lower or upper case, but not a mix...
180273471bf0Spatrick   // except in MASM, which uses full case-insensitivity.
180373471bf0Spatrick   if (Name.compare(Name.lower()) && Name.compare(Name.upper()) &&
180473471bf0Spatrick       !getParser().isParsingMasm())
180509467b48Spatrick     return false;
180673471bf0Spatrick   if (Name.equals_insensitive("not")) {
180709467b48Spatrick     SM.onNot();
180873471bf0Spatrick   } else if (Name.equals_insensitive("or")) {
180909467b48Spatrick     SM.onOr();
181073471bf0Spatrick   } else if (Name.equals_insensitive("shl")) {
181109467b48Spatrick     SM.onLShift();
181273471bf0Spatrick   } else if (Name.equals_insensitive("shr")) {
181309467b48Spatrick     SM.onRShift();
181473471bf0Spatrick   } else if (Name.equals_insensitive("xor")) {
181509467b48Spatrick     SM.onXor();
181673471bf0Spatrick   } else if (Name.equals_insensitive("and")) {
181709467b48Spatrick     SM.onAnd();
181873471bf0Spatrick   } else if (Name.equals_insensitive("mod")) {
181909467b48Spatrick     SM.onMod();
182073471bf0Spatrick   } else if (Name.equals_insensitive("offset")) {
182109467b48Spatrick     SMLoc OffsetLoc = getTok().getLoc();
182209467b48Spatrick     const MCExpr *Val = nullptr;
182309467b48Spatrick     StringRef ID;
182409467b48Spatrick     InlineAsmIdentifierInfo Info;
182509467b48Spatrick     ParseError = ParseIntelOffsetOperator(Val, ID, Info, End);
182609467b48Spatrick     if (ParseError)
182709467b48Spatrick       return true;
182809467b48Spatrick     StringRef ErrMsg;
182909467b48Spatrick     ParseError =
1830097a140dSpatrick         SM.onOffset(Val, OffsetLoc, ID, Info, isParsingMSInlineAsm(), ErrMsg);
183109467b48Spatrick     if (ParseError)
183209467b48Spatrick       return Error(SMLoc::getFromPointer(Name.data()), ErrMsg);
183309467b48Spatrick   } else {
183409467b48Spatrick     return false;
183509467b48Spatrick   }
183673471bf0Spatrick   if (!Name.equals_insensitive("offset"))
183773471bf0Spatrick     End = consumeToken();
183873471bf0Spatrick   return true;
183973471bf0Spatrick }
ParseMasmNamedOperator(StringRef Name,IntelExprStateMachine & SM,bool & ParseError,SMLoc & End)184073471bf0Spatrick bool X86AsmParser::ParseMasmNamedOperator(StringRef Name,
184173471bf0Spatrick                                           IntelExprStateMachine &SM,
184273471bf0Spatrick                                           bool &ParseError, SMLoc &End) {
184373471bf0Spatrick   if (Name.equals_insensitive("eq")) {
184473471bf0Spatrick     SM.onEq();
184573471bf0Spatrick   } else if (Name.equals_insensitive("ne")) {
184673471bf0Spatrick     SM.onNE();
184773471bf0Spatrick   } else if (Name.equals_insensitive("lt")) {
184873471bf0Spatrick     SM.onLT();
184973471bf0Spatrick   } else if (Name.equals_insensitive("le")) {
185073471bf0Spatrick     SM.onLE();
185173471bf0Spatrick   } else if (Name.equals_insensitive("gt")) {
185273471bf0Spatrick     SM.onGT();
185373471bf0Spatrick   } else if (Name.equals_insensitive("ge")) {
185473471bf0Spatrick     SM.onGE();
185573471bf0Spatrick   } else {
185673471bf0Spatrick     return false;
185773471bf0Spatrick   }
185809467b48Spatrick   End = consumeToken();
185909467b48Spatrick   return true;
186009467b48Spatrick }
186109467b48Spatrick 
1862*d415bd75Srobert // Check if current intel expression append after an operand.
1863*d415bd75Srobert // Like: [Operand][Intel Expression]
tryParseOperandIdx(AsmToken::TokenKind PrevTK,IntelExprStateMachine & SM)1864*d415bd75Srobert void X86AsmParser::tryParseOperandIdx(AsmToken::TokenKind PrevTK,
1865*d415bd75Srobert                                       IntelExprStateMachine &SM) {
1866*d415bd75Srobert   if (PrevTK != AsmToken::RBrac)
1867*d415bd75Srobert     return;
1868*d415bd75Srobert 
1869*d415bd75Srobert   SM.setAppendAfterOperand();
1870*d415bd75Srobert }
1871*d415bd75Srobert 
ParseIntelExpression(IntelExprStateMachine & SM,SMLoc & End)187209467b48Spatrick bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
187309467b48Spatrick   MCAsmParser &Parser = getParser();
187409467b48Spatrick   StringRef ErrMsg;
187509467b48Spatrick 
187609467b48Spatrick   AsmToken::TokenKind PrevTK = AsmToken::Error;
1877*d415bd75Srobert 
1878*d415bd75Srobert   if (getContext().getObjectFileInfo()->isPositionIndependent())
1879*d415bd75Srobert     SM.setPIC();
1880*d415bd75Srobert 
188109467b48Spatrick   bool Done = false;
188209467b48Spatrick   while (!Done) {
188373471bf0Spatrick     // Get a fresh reference on each loop iteration in case the previous
188473471bf0Spatrick     // iteration moved the token storage during UnLex().
188573471bf0Spatrick     const AsmToken &Tok = Parser.getTok();
188673471bf0Spatrick 
188709467b48Spatrick     bool UpdateLocLex = true;
188809467b48Spatrick     AsmToken::TokenKind TK = getLexer().getKind();
188909467b48Spatrick 
189009467b48Spatrick     switch (TK) {
189109467b48Spatrick     default:
189209467b48Spatrick       if ((Done = SM.isValidEndState()))
189309467b48Spatrick         break;
189409467b48Spatrick       return Error(Tok.getLoc(), "unknown token in expression");
189573471bf0Spatrick     case AsmToken::Error:
189673471bf0Spatrick       return Error(getLexer().getErrLoc(), getLexer().getErr());
189773471bf0Spatrick       break;
189809467b48Spatrick     case AsmToken::EndOfStatement:
189909467b48Spatrick       Done = true;
190009467b48Spatrick       break;
190109467b48Spatrick     case AsmToken::Real:
190209467b48Spatrick       // DotOperator: [ebx].0
190309467b48Spatrick       UpdateLocLex = false;
190409467b48Spatrick       if (ParseIntelDotOperator(SM, End))
190509467b48Spatrick         return true;
190609467b48Spatrick       break;
190773471bf0Spatrick     case AsmToken::Dot:
190873471bf0Spatrick       if (!Parser.isParsingMasm()) {
190973471bf0Spatrick         if ((Done = SM.isValidEndState()))
191073471bf0Spatrick           break;
191173471bf0Spatrick         return Error(Tok.getLoc(), "unknown token in expression");
191273471bf0Spatrick       }
191373471bf0Spatrick       // MASM allows spaces around the dot operator (e.g., "var . x")
191473471bf0Spatrick       Lex();
191573471bf0Spatrick       UpdateLocLex = false;
191673471bf0Spatrick       if (ParseIntelDotOperator(SM, End))
191773471bf0Spatrick         return true;
191873471bf0Spatrick       break;
191973471bf0Spatrick     case AsmToken::Dollar:
192073471bf0Spatrick       if (!Parser.isParsingMasm()) {
192173471bf0Spatrick         if ((Done = SM.isValidEndState()))
192273471bf0Spatrick           break;
192373471bf0Spatrick         return Error(Tok.getLoc(), "unknown token in expression");
192473471bf0Spatrick       }
1925*d415bd75Srobert       [[fallthrough]];
192673471bf0Spatrick     case AsmToken::String: {
192773471bf0Spatrick       if (Parser.isParsingMasm()) {
192873471bf0Spatrick         // MASM parsers handle strings in expressions as constants.
192973471bf0Spatrick         SMLoc ValueLoc = Tok.getLoc();
193073471bf0Spatrick         int64_t Res;
193173471bf0Spatrick         const MCExpr *Val;
193273471bf0Spatrick         if (Parser.parsePrimaryExpr(Val, End, nullptr))
193373471bf0Spatrick           return true;
193473471bf0Spatrick         UpdateLocLex = false;
193573471bf0Spatrick         if (!Val->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
193673471bf0Spatrick           return Error(ValueLoc, "expected absolute value");
193773471bf0Spatrick         if (SM.onInteger(Res, ErrMsg))
193873471bf0Spatrick           return Error(ValueLoc, ErrMsg);
193973471bf0Spatrick         break;
194073471bf0Spatrick       }
1941*d415bd75Srobert       [[fallthrough]];
194273471bf0Spatrick     }
194309467b48Spatrick     case AsmToken::At:
194409467b48Spatrick     case AsmToken::Identifier: {
194509467b48Spatrick       SMLoc IdentLoc = Tok.getLoc();
194609467b48Spatrick       StringRef Identifier = Tok.getString();
194709467b48Spatrick       UpdateLocLex = false;
194873471bf0Spatrick       if (Parser.isParsingMasm()) {
194973471bf0Spatrick         size_t DotOffset = Identifier.find_first_of('.');
195073471bf0Spatrick         if (DotOffset != StringRef::npos) {
195173471bf0Spatrick           consumeToken();
195273471bf0Spatrick           StringRef LHS = Identifier.slice(0, DotOffset);
195373471bf0Spatrick           StringRef Dot = Identifier.slice(DotOffset, DotOffset + 1);
195473471bf0Spatrick           StringRef RHS = Identifier.slice(DotOffset + 1, StringRef::npos);
195573471bf0Spatrick           if (!RHS.empty()) {
195673471bf0Spatrick             getLexer().UnLex(AsmToken(AsmToken::Identifier, RHS));
195773471bf0Spatrick           }
195873471bf0Spatrick           getLexer().UnLex(AsmToken(AsmToken::Dot, Dot));
195973471bf0Spatrick           if (!LHS.empty()) {
196073471bf0Spatrick             getLexer().UnLex(AsmToken(AsmToken::Identifier, LHS));
196173471bf0Spatrick           }
196273471bf0Spatrick           break;
196373471bf0Spatrick         }
196473471bf0Spatrick       }
1965097a140dSpatrick       // (MASM only) <TYPE> PTR operator
1966097a140dSpatrick       if (Parser.isParsingMasm()) {
1967097a140dSpatrick         const AsmToken &NextTok = getLexer().peekTok();
1968097a140dSpatrick         if (NextTok.is(AsmToken::Identifier) &&
196973471bf0Spatrick             NextTok.getIdentifier().equals_insensitive("ptr")) {
197073471bf0Spatrick           AsmTypeInfo Info;
197173471bf0Spatrick           if (Parser.lookUpType(Identifier, Info))
197273471bf0Spatrick             return Error(Tok.getLoc(), "unknown type");
197373471bf0Spatrick           SM.onCast(Info);
1974097a140dSpatrick           // Eat type and PTR.
1975097a140dSpatrick           consumeToken();
1976097a140dSpatrick           End = consumeToken();
197709467b48Spatrick           break;
197809467b48Spatrick         }
1979097a140dSpatrick       }
1980097a140dSpatrick       // Register, or (MASM only) <register>.<field>
1981*d415bd75Srobert       MCRegister Reg;
1982097a140dSpatrick       if (Tok.is(AsmToken::Identifier)) {
1983097a140dSpatrick         if (!ParseRegister(Reg, IdentLoc, End, /*RestoreOnFailure=*/true)) {
1984097a140dSpatrick           if (SM.onRegister(Reg, ErrMsg))
1985097a140dSpatrick             return Error(IdentLoc, ErrMsg);
1986097a140dSpatrick           break;
1987097a140dSpatrick         }
1988097a140dSpatrick         if (Parser.isParsingMasm()) {
1989097a140dSpatrick           const std::pair<StringRef, StringRef> IDField =
1990097a140dSpatrick               Tok.getString().split('.');
1991097a140dSpatrick           const StringRef ID = IDField.first, Field = IDField.second;
1992097a140dSpatrick           SMLoc IDEndLoc = SMLoc::getFromPointer(ID.data() + ID.size());
1993097a140dSpatrick           if (!Field.empty() &&
1994097a140dSpatrick               !MatchRegisterByName(Reg, ID, IdentLoc, IDEndLoc)) {
1995097a140dSpatrick             if (SM.onRegister(Reg, ErrMsg))
1996097a140dSpatrick               return Error(IdentLoc, ErrMsg);
1997097a140dSpatrick 
199873471bf0Spatrick             AsmFieldInfo Info;
1999097a140dSpatrick             SMLoc FieldStartLoc = SMLoc::getFromPointer(Field.data());
200073471bf0Spatrick             if (Parser.lookUpField(Field, Info))
2001097a140dSpatrick               return Error(FieldStartLoc, "unknown offset");
2002097a140dSpatrick             else if (SM.onPlus(ErrMsg))
2003097a140dSpatrick               return Error(getTok().getLoc(), ErrMsg);
200473471bf0Spatrick             else if (SM.onInteger(Info.Offset, ErrMsg))
2005097a140dSpatrick               return Error(IdentLoc, ErrMsg);
200673471bf0Spatrick             SM.setTypeInfo(Info.Type);
2007097a140dSpatrick 
2008097a140dSpatrick             End = consumeToken();
2009097a140dSpatrick             break;
2010097a140dSpatrick           }
2011097a140dSpatrick         }
2012097a140dSpatrick       }
201309467b48Spatrick       // Operator synonymous ("not", "or" etc.)
201409467b48Spatrick       bool ParseError = false;
201509467b48Spatrick       if (ParseIntelNamedOperator(Identifier, SM, ParseError, End)) {
201609467b48Spatrick         if (ParseError)
201709467b48Spatrick           return true;
201809467b48Spatrick         break;
201909467b48Spatrick       }
202073471bf0Spatrick       if (Parser.isParsingMasm() &&
202173471bf0Spatrick           ParseMasmNamedOperator(Identifier, SM, ParseError, End)) {
202273471bf0Spatrick         if (ParseError)
202373471bf0Spatrick           return true;
202473471bf0Spatrick         break;
202573471bf0Spatrick       }
202609467b48Spatrick       // Symbol reference, when parsing assembly content
202709467b48Spatrick       InlineAsmIdentifierInfo Info;
202873471bf0Spatrick       AsmFieldInfo FieldInfo;
202909467b48Spatrick       const MCExpr *Val;
2030097a140dSpatrick       if (isParsingMSInlineAsm() || Parser.isParsingMasm()) {
2031097a140dSpatrick         // MS Dot Operator expression
2032097a140dSpatrick         if (Identifier.count('.') &&
2033097a140dSpatrick             (PrevTK == AsmToken::RBrac || PrevTK == AsmToken::RParen)) {
2034097a140dSpatrick           if (ParseIntelDotOperator(SM, End))
2035097a140dSpatrick             return true;
203609467b48Spatrick           break;
203709467b48Spatrick         }
2038097a140dSpatrick       }
2039097a140dSpatrick       if (isParsingMSInlineAsm()) {
204009467b48Spatrick         // MS InlineAsm operators (TYPE/LENGTH/SIZE)
204109467b48Spatrick         if (unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {
204209467b48Spatrick           if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {
204309467b48Spatrick             if (SM.onInteger(Val, ErrMsg))
204409467b48Spatrick               return Error(IdentLoc, ErrMsg);
204573471bf0Spatrick           } else {
204609467b48Spatrick             return true;
204773471bf0Spatrick           }
204809467b48Spatrick           break;
204909467b48Spatrick         }
205009467b48Spatrick         // MS InlineAsm identifier
205109467b48Spatrick         // Call parseIdentifier() to combine @ with the identifier behind it.
205209467b48Spatrick         if (TK == AsmToken::At && Parser.parseIdentifier(Identifier))
205309467b48Spatrick           return Error(IdentLoc, "expected identifier");
205409467b48Spatrick         if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info, false, End))
205509467b48Spatrick           return true;
205673471bf0Spatrick         else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.Type,
205773471bf0Spatrick                                      true, ErrMsg))
205809467b48Spatrick           return Error(IdentLoc, ErrMsg);
205909467b48Spatrick         break;
206009467b48Spatrick       }
206173471bf0Spatrick       if (Parser.isParsingMasm()) {
206273471bf0Spatrick         if (unsigned OpKind = IdentifyMasmOperator(Identifier)) {
206373471bf0Spatrick           int64_t Val;
206473471bf0Spatrick           if (ParseMasmOperator(OpKind, Val))
206573471bf0Spatrick             return true;
206673471bf0Spatrick           if (SM.onInteger(Val, ErrMsg))
206773471bf0Spatrick             return Error(IdentLoc, ErrMsg);
206873471bf0Spatrick           break;
206973471bf0Spatrick         }
207073471bf0Spatrick         if (!getParser().lookUpType(Identifier, FieldInfo.Type)) {
207173471bf0Spatrick           // Field offset immediate; <TYPE>.<field specification>
207273471bf0Spatrick           Lex(); // eat type
207373471bf0Spatrick           bool EndDot = parseOptionalToken(AsmToken::Dot);
207473471bf0Spatrick           while (EndDot || (getTok().is(AsmToken::Identifier) &&
207573471bf0Spatrick                             getTok().getString().startswith("."))) {
207673471bf0Spatrick             getParser().parseIdentifier(Identifier);
207773471bf0Spatrick             if (!EndDot)
207873471bf0Spatrick               Identifier.consume_front(".");
207973471bf0Spatrick             EndDot = Identifier.consume_back(".");
208073471bf0Spatrick             if (getParser().lookUpField(FieldInfo.Type.Name, Identifier,
208173471bf0Spatrick                                         FieldInfo)) {
208273471bf0Spatrick               SMLoc IDEnd =
208373471bf0Spatrick                   SMLoc::getFromPointer(Identifier.data() + Identifier.size());
208473471bf0Spatrick               return Error(IdentLoc, "Unable to lookup field reference!",
208573471bf0Spatrick                            SMRange(IdentLoc, IDEnd));
208673471bf0Spatrick             }
208773471bf0Spatrick             if (!EndDot)
208873471bf0Spatrick               EndDot = parseOptionalToken(AsmToken::Dot);
208973471bf0Spatrick           }
209073471bf0Spatrick           if (SM.onInteger(FieldInfo.Offset, ErrMsg))
209173471bf0Spatrick             return Error(IdentLoc, ErrMsg);
209273471bf0Spatrick           break;
209373471bf0Spatrick         }
209473471bf0Spatrick       }
209573471bf0Spatrick       if (getParser().parsePrimaryExpr(Val, End, &FieldInfo.Type)) {
2096097a140dSpatrick         return Error(Tok.getLoc(), "Unexpected identifier!");
209773471bf0Spatrick       } else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.Type,
209873471bf0Spatrick                                      false, ErrMsg)) {
2099097a140dSpatrick         return Error(IdentLoc, ErrMsg);
2100097a140dSpatrick       }
2101097a140dSpatrick       break;
2102097a140dSpatrick     }
210309467b48Spatrick     case AsmToken::Integer: {
210409467b48Spatrick       // Look for 'b' or 'f' following an Integer as a directional label
210509467b48Spatrick       SMLoc Loc = getTok().getLoc();
210609467b48Spatrick       int64_t IntVal = getTok().getIntVal();
210709467b48Spatrick       End = consumeToken();
210809467b48Spatrick       UpdateLocLex = false;
210909467b48Spatrick       if (getLexer().getKind() == AsmToken::Identifier) {
211009467b48Spatrick         StringRef IDVal = getTok().getString();
211109467b48Spatrick         if (IDVal == "f" || IDVal == "b") {
211209467b48Spatrick           MCSymbol *Sym =
211309467b48Spatrick               getContext().getDirectionalLocalSymbol(IntVal, IDVal == "b");
211409467b48Spatrick           MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
211509467b48Spatrick           const MCExpr *Val =
211609467b48Spatrick               MCSymbolRefExpr::create(Sym, Variant, getContext());
211709467b48Spatrick           if (IDVal == "b" && Sym->isUndefined())
211809467b48Spatrick             return Error(Loc, "invalid reference to undefined symbol");
211909467b48Spatrick           StringRef Identifier = Sym->getName();
212009467b48Spatrick           InlineAsmIdentifierInfo Info;
212173471bf0Spatrick           AsmTypeInfo Type;
212273471bf0Spatrick           if (SM.onIdentifierExpr(Val, Identifier, Info, Type,
212373471bf0Spatrick                                   isParsingMSInlineAsm(), ErrMsg))
212409467b48Spatrick             return Error(Loc, ErrMsg);
212509467b48Spatrick           End = consumeToken();
212609467b48Spatrick         } else {
212709467b48Spatrick           if (SM.onInteger(IntVal, ErrMsg))
212809467b48Spatrick             return Error(Loc, ErrMsg);
212909467b48Spatrick         }
213009467b48Spatrick       } else {
213109467b48Spatrick         if (SM.onInteger(IntVal, ErrMsg))
213209467b48Spatrick           return Error(Loc, ErrMsg);
213309467b48Spatrick       }
213409467b48Spatrick       break;
213509467b48Spatrick     }
213609467b48Spatrick     case AsmToken::Plus:
213709467b48Spatrick       if (SM.onPlus(ErrMsg))
213809467b48Spatrick         return Error(getTok().getLoc(), ErrMsg);
213909467b48Spatrick       break;
214009467b48Spatrick     case AsmToken::Minus:
214109467b48Spatrick       if (SM.onMinus(ErrMsg))
214209467b48Spatrick         return Error(getTok().getLoc(), ErrMsg);
214309467b48Spatrick       break;
214409467b48Spatrick     case AsmToken::Tilde:   SM.onNot(); break;
214509467b48Spatrick     case AsmToken::Star:    SM.onStar(); break;
214609467b48Spatrick     case AsmToken::Slash:   SM.onDivide(); break;
214709467b48Spatrick     case AsmToken::Percent: SM.onMod(); break;
214809467b48Spatrick     case AsmToken::Pipe:    SM.onOr(); break;
214909467b48Spatrick     case AsmToken::Caret:   SM.onXor(); break;
215009467b48Spatrick     case AsmToken::Amp:     SM.onAnd(); break;
215109467b48Spatrick     case AsmToken::LessLess:
215209467b48Spatrick                             SM.onLShift(); break;
215309467b48Spatrick     case AsmToken::GreaterGreater:
215409467b48Spatrick                             SM.onRShift(); break;
215509467b48Spatrick     case AsmToken::LBrac:
215609467b48Spatrick       if (SM.onLBrac())
215709467b48Spatrick         return Error(Tok.getLoc(), "unexpected bracket encountered");
2158*d415bd75Srobert       tryParseOperandIdx(PrevTK, SM);
215909467b48Spatrick       break;
216009467b48Spatrick     case AsmToken::RBrac:
2161*d415bd75Srobert       if (SM.onRBrac(ErrMsg)) {
2162*d415bd75Srobert         return Error(Tok.getLoc(), ErrMsg);
2163*d415bd75Srobert       }
216409467b48Spatrick       break;
216509467b48Spatrick     case AsmToken::LParen:  SM.onLParen(); break;
216609467b48Spatrick     case AsmToken::RParen:  SM.onRParen(); break;
216709467b48Spatrick     }
216809467b48Spatrick     if (SM.hadError())
216909467b48Spatrick       return Error(Tok.getLoc(), "unknown token in expression");
217009467b48Spatrick 
217109467b48Spatrick     if (!Done && UpdateLocLex)
217209467b48Spatrick       End = consumeToken();
217309467b48Spatrick 
217409467b48Spatrick     PrevTK = TK;
217509467b48Spatrick   }
217609467b48Spatrick   return false;
217709467b48Spatrick }
217809467b48Spatrick 
RewriteIntelExpression(IntelExprStateMachine & SM,SMLoc Start,SMLoc End)217909467b48Spatrick void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &SM,
218009467b48Spatrick                                           SMLoc Start, SMLoc End) {
218109467b48Spatrick   SMLoc Loc = Start;
218209467b48Spatrick   unsigned ExprLen = End.getPointer() - Start.getPointer();
218309467b48Spatrick   // Skip everything before a symbol displacement (if we have one)
218409467b48Spatrick   if (SM.getSym() && !SM.isOffsetOperator()) {
218509467b48Spatrick     StringRef SymName = SM.getSymName();
218609467b48Spatrick     if (unsigned Len = SymName.data() - Start.getPointer())
218709467b48Spatrick       InstInfo->AsmRewrites->emplace_back(AOK_Skip, Start, Len);
218809467b48Spatrick     Loc = SMLoc::getFromPointer(SymName.data() + SymName.size());
218909467b48Spatrick     ExprLen = End.getPointer() - (SymName.data() + SymName.size());
219009467b48Spatrick     // If we have only a symbol than there's no need for complex rewrite,
219109467b48Spatrick     // simply skip everything after it
219209467b48Spatrick     if (!(SM.getBaseReg() || SM.getIndexReg() || SM.getImm())) {
219309467b48Spatrick       if (ExprLen)
219409467b48Spatrick         InstInfo->AsmRewrites->emplace_back(AOK_Skip, Loc, ExprLen);
219509467b48Spatrick       return;
219609467b48Spatrick     }
219709467b48Spatrick   }
219809467b48Spatrick   // Build an Intel Expression rewrite
219909467b48Spatrick   StringRef BaseRegStr;
220009467b48Spatrick   StringRef IndexRegStr;
220109467b48Spatrick   StringRef OffsetNameStr;
220209467b48Spatrick   if (SM.getBaseReg())
220309467b48Spatrick     BaseRegStr = X86IntelInstPrinter::getRegisterName(SM.getBaseReg());
220409467b48Spatrick   if (SM.getIndexReg())
220509467b48Spatrick     IndexRegStr = X86IntelInstPrinter::getRegisterName(SM.getIndexReg());
220609467b48Spatrick   if (SM.isOffsetOperator())
220709467b48Spatrick     OffsetNameStr = SM.getSymName();
220809467b48Spatrick   // Emit it
220909467b48Spatrick   IntelExpr Expr(BaseRegStr, IndexRegStr, SM.getScale(), OffsetNameStr,
221009467b48Spatrick                  SM.getImm(), SM.isMemExpr());
221109467b48Spatrick   InstInfo->AsmRewrites->emplace_back(Loc, ExprLen, Expr);
221209467b48Spatrick }
221309467b48Spatrick 
221409467b48Spatrick // Inline assembly may use variable names with namespace alias qualifiers.
ParseIntelInlineAsmIdentifier(const MCExpr * & Val,StringRef & Identifier,InlineAsmIdentifierInfo & Info,bool IsUnevaluatedOperand,SMLoc & End,bool IsParsingOffsetOperator)221509467b48Spatrick bool X86AsmParser::ParseIntelInlineAsmIdentifier(
221609467b48Spatrick     const MCExpr *&Val, StringRef &Identifier, InlineAsmIdentifierInfo &Info,
221709467b48Spatrick     bool IsUnevaluatedOperand, SMLoc &End, bool IsParsingOffsetOperator) {
221809467b48Spatrick   MCAsmParser &Parser = getParser();
2219097a140dSpatrick   assert(isParsingMSInlineAsm() && "Expected to be parsing inline assembly.");
222009467b48Spatrick   Val = nullptr;
222109467b48Spatrick 
222209467b48Spatrick   StringRef LineBuf(Identifier.data());
222309467b48Spatrick   SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
222409467b48Spatrick 
222509467b48Spatrick   const AsmToken &Tok = Parser.getTok();
222609467b48Spatrick   SMLoc Loc = Tok.getLoc();
222709467b48Spatrick 
222809467b48Spatrick   // Advance the token stream until the end of the current token is
222909467b48Spatrick   // after the end of what the frontend claimed.
223009467b48Spatrick   const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size();
223109467b48Spatrick   do {
223209467b48Spatrick     End = Tok.getEndLoc();
223309467b48Spatrick     getLexer().Lex();
223409467b48Spatrick   } while (End.getPointer() < EndPtr);
223509467b48Spatrick   Identifier = LineBuf;
223609467b48Spatrick 
223709467b48Spatrick   // The frontend should end parsing on an assembler token boundary, unless it
223809467b48Spatrick   // failed parsing.
223909467b48Spatrick   assert((End.getPointer() == EndPtr ||
224009467b48Spatrick           Info.isKind(InlineAsmIdentifierInfo::IK_Invalid)) &&
224109467b48Spatrick           "frontend claimed part of a token?");
224209467b48Spatrick 
224309467b48Spatrick   // If the identifier lookup was unsuccessful, assume that we are dealing with
224409467b48Spatrick   // a label.
224509467b48Spatrick   if (Info.isKind(InlineAsmIdentifierInfo::IK_Invalid)) {
224609467b48Spatrick     StringRef InternalName =
224709467b48Spatrick       SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
224809467b48Spatrick                                          Loc, false);
224909467b48Spatrick     assert(InternalName.size() && "We should have an internal name here.");
225009467b48Spatrick     // Push a rewrite for replacing the identifier name with the internal name,
225109467b48Spatrick     // unless we are parsing the operand of an offset operator
225209467b48Spatrick     if (!IsParsingOffsetOperator)
225309467b48Spatrick       InstInfo->AsmRewrites->emplace_back(AOK_Label, Loc, Identifier.size(),
225409467b48Spatrick                                           InternalName);
225509467b48Spatrick     else
225609467b48Spatrick       Identifier = InternalName;
225709467b48Spatrick   } else if (Info.isKind(InlineAsmIdentifierInfo::IK_EnumVal))
225809467b48Spatrick     return false;
225909467b48Spatrick   // Create the symbol reference.
226009467b48Spatrick   MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
226109467b48Spatrick   MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
226209467b48Spatrick   Val = MCSymbolRefExpr::create(Sym, Variant, getParser().getContext());
226309467b48Spatrick   return false;
226409467b48Spatrick }
226509467b48Spatrick 
226609467b48Spatrick //ParseRoundingModeOp - Parse AVX-512 rounding mode operand
ParseRoundingModeOp(SMLoc Start,OperandVector & Operands)226773471bf0Spatrick bool X86AsmParser::ParseRoundingModeOp(SMLoc Start, OperandVector &Operands) {
226809467b48Spatrick   MCAsmParser &Parser = getParser();
226909467b48Spatrick   const AsmToken &Tok = Parser.getTok();
227009467b48Spatrick   // Eat "{" and mark the current place.
227109467b48Spatrick   const SMLoc consumedToken = consumeToken();
227209467b48Spatrick   if (Tok.isNot(AsmToken::Identifier))
227373471bf0Spatrick     return Error(Tok.getLoc(), "Expected an identifier after {");
227409467b48Spatrick   if (Tok.getIdentifier().startswith("r")){
227509467b48Spatrick     int rndMode = StringSwitch<int>(Tok.getIdentifier())
227609467b48Spatrick       .Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
227709467b48Spatrick       .Case("rd", X86::STATIC_ROUNDING::TO_NEG_INF)
227809467b48Spatrick       .Case("ru", X86::STATIC_ROUNDING::TO_POS_INF)
227909467b48Spatrick       .Case("rz", X86::STATIC_ROUNDING::TO_ZERO)
228009467b48Spatrick       .Default(-1);
228109467b48Spatrick     if (-1 == rndMode)
228273471bf0Spatrick       return Error(Tok.getLoc(), "Invalid rounding mode.");
228309467b48Spatrick      Parser.Lex();  // Eat "r*" of r*-sae
228409467b48Spatrick     if (!getLexer().is(AsmToken::Minus))
228573471bf0Spatrick       return Error(Tok.getLoc(), "Expected - at this point");
228609467b48Spatrick     Parser.Lex();  // Eat "-"
228709467b48Spatrick     Parser.Lex();  // Eat the sae
228809467b48Spatrick     if (!getLexer().is(AsmToken::RCurly))
228973471bf0Spatrick       return Error(Tok.getLoc(), "Expected } at this point");
229009467b48Spatrick     SMLoc End = Tok.getEndLoc();
229109467b48Spatrick     Parser.Lex();  // Eat "}"
229209467b48Spatrick     const MCExpr *RndModeOp =
229309467b48Spatrick       MCConstantExpr::create(rndMode, Parser.getContext());
229473471bf0Spatrick     Operands.push_back(X86Operand::CreateImm(RndModeOp, Start, End));
229573471bf0Spatrick     return false;
229609467b48Spatrick   }
229709467b48Spatrick   if(Tok.getIdentifier().equals("sae")){
229809467b48Spatrick     Parser.Lex();  // Eat the sae
229909467b48Spatrick     if (!getLexer().is(AsmToken::RCurly))
230073471bf0Spatrick       return Error(Tok.getLoc(), "Expected } at this point");
230109467b48Spatrick     Parser.Lex();  // Eat "}"
230273471bf0Spatrick     Operands.push_back(X86Operand::CreateToken("{sae}", consumedToken));
230373471bf0Spatrick     return false;
230409467b48Spatrick   }
230573471bf0Spatrick   return Error(Tok.getLoc(), "unknown token in expression");
230609467b48Spatrick }
230709467b48Spatrick 
230809467b48Spatrick /// Parse the '.' operator.
ParseIntelDotOperator(IntelExprStateMachine & SM,SMLoc & End)2309097a140dSpatrick bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &SM,
2310097a140dSpatrick                                          SMLoc &End) {
231109467b48Spatrick   const AsmToken &Tok = getTok();
231273471bf0Spatrick   AsmFieldInfo Info;
231309467b48Spatrick 
231409467b48Spatrick   // Drop the optional '.'.
231509467b48Spatrick   StringRef DotDispStr = Tok.getString();
231609467b48Spatrick   if (DotDispStr.startswith("."))
231709467b48Spatrick     DotDispStr = DotDispStr.drop_front(1);
231873471bf0Spatrick   StringRef TrailingDot;
231909467b48Spatrick 
232009467b48Spatrick   // .Imm gets lexed as a real.
232109467b48Spatrick   if (Tok.is(AsmToken::Real)) {
232209467b48Spatrick     APInt DotDisp;
232309467b48Spatrick     DotDispStr.getAsInteger(10, DotDisp);
232473471bf0Spatrick     Info.Offset = DotDisp.getZExtValue();
2325097a140dSpatrick   } else if ((isParsingMSInlineAsm() || getParser().isParsingMasm()) &&
2326097a140dSpatrick              Tok.is(AsmToken::Identifier)) {
232773471bf0Spatrick     if (DotDispStr.endswith(".")) {
232873471bf0Spatrick       TrailingDot = DotDispStr.substr(DotDispStr.size() - 1);
232973471bf0Spatrick       DotDispStr = DotDispStr.drop_back(1);
233073471bf0Spatrick     }
2331097a140dSpatrick     const std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
2332097a140dSpatrick     const StringRef Base = BaseMember.first, Member = BaseMember.second;
233373471bf0Spatrick     if (getParser().lookUpField(SM.getType(), DotDispStr, Info) &&
233473471bf0Spatrick         getParser().lookUpField(SM.getSymName(), DotDispStr, Info) &&
233573471bf0Spatrick         getParser().lookUpField(DotDispStr, Info) &&
2336097a140dSpatrick         (!SemaCallback ||
233773471bf0Spatrick          SemaCallback->LookupInlineAsmField(Base, Member, Info.Offset)))
233809467b48Spatrick       return Error(Tok.getLoc(), "Unable to lookup field reference!");
233973471bf0Spatrick   } else {
234009467b48Spatrick     return Error(Tok.getLoc(), "Unexpected token type!");
234173471bf0Spatrick   }
234209467b48Spatrick 
234309467b48Spatrick   // Eat the DotExpression and update End
234409467b48Spatrick   End = SMLoc::getFromPointer(DotDispStr.data());
234509467b48Spatrick   const char *DotExprEndLoc = DotDispStr.data() + DotDispStr.size();
234609467b48Spatrick   while (Tok.getLoc().getPointer() < DotExprEndLoc)
234709467b48Spatrick     Lex();
234873471bf0Spatrick   if (!TrailingDot.empty())
234973471bf0Spatrick     getLexer().UnLex(AsmToken(AsmToken::Dot, TrailingDot));
235073471bf0Spatrick   SM.addImm(Info.Offset);
235173471bf0Spatrick   SM.setTypeInfo(Info.Type);
235209467b48Spatrick   return false;
235309467b48Spatrick }
235409467b48Spatrick 
235509467b48Spatrick /// Parse the 'offset' operator.
235609467b48Spatrick /// This operator is used to specify the location of a given operand
ParseIntelOffsetOperator(const MCExpr * & Val,StringRef & ID,InlineAsmIdentifierInfo & Info,SMLoc & End)235709467b48Spatrick bool X86AsmParser::ParseIntelOffsetOperator(const MCExpr *&Val, StringRef &ID,
235809467b48Spatrick                                             InlineAsmIdentifierInfo &Info,
235909467b48Spatrick                                             SMLoc &End) {
236009467b48Spatrick   // Eat offset, mark start of identifier.
236109467b48Spatrick   SMLoc Start = Lex().getLoc();
236209467b48Spatrick   ID = getTok().getString();
2363097a140dSpatrick   if (!isParsingMSInlineAsm()) {
236409467b48Spatrick     if ((getTok().isNot(AsmToken::Identifier) &&
236509467b48Spatrick          getTok().isNot(AsmToken::String)) ||
236673471bf0Spatrick         getParser().parsePrimaryExpr(Val, End, nullptr))
236709467b48Spatrick       return Error(Start, "unexpected token!");
236809467b48Spatrick   } else if (ParseIntelInlineAsmIdentifier(Val, ID, Info, false, End, true)) {
236909467b48Spatrick     return Error(Start, "unable to lookup expression");
237009467b48Spatrick   } else if (Info.isKind(InlineAsmIdentifierInfo::IK_EnumVal)) {
237109467b48Spatrick     return Error(Start, "offset operator cannot yet handle constants");
237209467b48Spatrick   }
237309467b48Spatrick   return false;
237409467b48Spatrick }
237509467b48Spatrick 
237609467b48Spatrick // Query a candidate string for being an Intel assembly operator
237709467b48Spatrick // Report back its kind, or IOK_INVALID if does not evaluated as a known one
IdentifyIntelInlineAsmOperator(StringRef Name)237809467b48Spatrick unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(StringRef Name) {
237909467b48Spatrick   return StringSwitch<unsigned>(Name)
238009467b48Spatrick     .Cases("TYPE","type",IOK_TYPE)
238109467b48Spatrick     .Cases("SIZE","size",IOK_SIZE)
238209467b48Spatrick     .Cases("LENGTH","length",IOK_LENGTH)
238309467b48Spatrick     .Default(IOK_INVALID);
238409467b48Spatrick }
238509467b48Spatrick 
238609467b48Spatrick /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators.  The LENGTH operator
238709467b48Spatrick /// returns the number of elements in an array.  It returns the value 1 for
238809467b48Spatrick /// non-array variables.  The SIZE operator returns the size of a C or C++
238909467b48Spatrick /// variable.  A variable's size is the product of its LENGTH and TYPE.  The
239009467b48Spatrick /// TYPE operator returns the size of a C or C++ type or variable. If the
239109467b48Spatrick /// variable is an array, TYPE returns the size of a single element.
ParseIntelInlineAsmOperator(unsigned OpKind)239209467b48Spatrick unsigned X86AsmParser::ParseIntelInlineAsmOperator(unsigned OpKind) {
239309467b48Spatrick   MCAsmParser &Parser = getParser();
239409467b48Spatrick   const AsmToken &Tok = Parser.getTok();
239509467b48Spatrick   Parser.Lex(); // Eat operator.
239609467b48Spatrick 
239709467b48Spatrick   const MCExpr *Val = nullptr;
239809467b48Spatrick   InlineAsmIdentifierInfo Info;
239909467b48Spatrick   SMLoc Start = Tok.getLoc(), End;
240009467b48Spatrick   StringRef Identifier = Tok.getString();
240109467b48Spatrick   if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
240273471bf0Spatrick                                     /*IsUnevaluatedOperand=*/true, End))
240309467b48Spatrick     return 0;
240409467b48Spatrick 
240509467b48Spatrick   if (!Info.isKind(InlineAsmIdentifierInfo::IK_Var)) {
240609467b48Spatrick     Error(Start, "unable to lookup expression");
240709467b48Spatrick     return 0;
240809467b48Spatrick   }
240909467b48Spatrick 
241009467b48Spatrick   unsigned CVal = 0;
241109467b48Spatrick   switch(OpKind) {
241209467b48Spatrick   default: llvm_unreachable("Unexpected operand kind!");
241309467b48Spatrick   case IOK_LENGTH: CVal = Info.Var.Length; break;
241409467b48Spatrick   case IOK_SIZE: CVal = Info.Var.Size; break;
241509467b48Spatrick   case IOK_TYPE: CVal = Info.Var.Type; break;
241609467b48Spatrick   }
241709467b48Spatrick 
241809467b48Spatrick   return CVal;
241909467b48Spatrick }
242009467b48Spatrick 
242173471bf0Spatrick // Query a candidate string for being an Intel assembly operator
242273471bf0Spatrick // Report back its kind, or IOK_INVALID if does not evaluated as a known one
IdentifyMasmOperator(StringRef Name)242373471bf0Spatrick unsigned X86AsmParser::IdentifyMasmOperator(StringRef Name) {
242473471bf0Spatrick   return StringSwitch<unsigned>(Name.lower())
242573471bf0Spatrick       .Case("type", MOK_TYPE)
242673471bf0Spatrick       .Cases("size", "sizeof", MOK_SIZEOF)
242773471bf0Spatrick       .Cases("length", "lengthof", MOK_LENGTHOF)
242873471bf0Spatrick       .Default(MOK_INVALID);
242973471bf0Spatrick }
243073471bf0Spatrick 
243173471bf0Spatrick /// Parse the 'LENGTHOF', 'SIZEOF', and 'TYPE' operators.  The LENGTHOF operator
243273471bf0Spatrick /// returns the number of elements in an array.  It returns the value 1 for
243373471bf0Spatrick /// non-array variables.  The SIZEOF operator returns the size of a type or
243473471bf0Spatrick /// variable in bytes.  A variable's size is the product of its LENGTH and TYPE.
243573471bf0Spatrick /// The TYPE operator returns the size of a variable. If the variable is an
243673471bf0Spatrick /// array, TYPE returns the size of a single element.
ParseMasmOperator(unsigned OpKind,int64_t & Val)243773471bf0Spatrick bool X86AsmParser::ParseMasmOperator(unsigned OpKind, int64_t &Val) {
243873471bf0Spatrick   MCAsmParser &Parser = getParser();
243973471bf0Spatrick   SMLoc OpLoc = Parser.getTok().getLoc();
244073471bf0Spatrick   Parser.Lex(); // Eat operator.
244173471bf0Spatrick 
244273471bf0Spatrick   Val = 0;
244373471bf0Spatrick   if (OpKind == MOK_SIZEOF || OpKind == MOK_TYPE) {
244473471bf0Spatrick     // Check for SIZEOF(<type>) and TYPE(<type>).
244573471bf0Spatrick     bool InParens = Parser.getTok().is(AsmToken::LParen);
244673471bf0Spatrick     const AsmToken &IDTok = InParens ? getLexer().peekTok() : Parser.getTok();
244773471bf0Spatrick     AsmTypeInfo Type;
244873471bf0Spatrick     if (IDTok.is(AsmToken::Identifier) &&
244973471bf0Spatrick         !Parser.lookUpType(IDTok.getIdentifier(), Type)) {
245073471bf0Spatrick       Val = Type.Size;
245173471bf0Spatrick 
245273471bf0Spatrick       // Eat tokens.
245373471bf0Spatrick       if (InParens)
245473471bf0Spatrick         parseToken(AsmToken::LParen);
245573471bf0Spatrick       parseToken(AsmToken::Identifier);
245673471bf0Spatrick       if (InParens)
245773471bf0Spatrick         parseToken(AsmToken::RParen);
245873471bf0Spatrick     }
245973471bf0Spatrick   }
246073471bf0Spatrick 
246173471bf0Spatrick   if (!Val) {
246273471bf0Spatrick     IntelExprStateMachine SM;
246373471bf0Spatrick     SMLoc End, Start = Parser.getTok().getLoc();
246473471bf0Spatrick     if (ParseIntelExpression(SM, End))
246573471bf0Spatrick       return true;
246673471bf0Spatrick 
246773471bf0Spatrick     switch (OpKind) {
246873471bf0Spatrick     default:
246973471bf0Spatrick       llvm_unreachable("Unexpected operand kind!");
247073471bf0Spatrick     case MOK_SIZEOF:
247173471bf0Spatrick       Val = SM.getSize();
247273471bf0Spatrick       break;
247373471bf0Spatrick     case MOK_LENGTHOF:
247473471bf0Spatrick       Val = SM.getLength();
247573471bf0Spatrick       break;
247673471bf0Spatrick     case MOK_TYPE:
247773471bf0Spatrick       Val = SM.getElementSize();
247873471bf0Spatrick       break;
247973471bf0Spatrick     }
248073471bf0Spatrick 
248173471bf0Spatrick     if (!Val)
248273471bf0Spatrick       return Error(OpLoc, "expression has unknown type", SMRange(Start, End));
248373471bf0Spatrick   }
248473471bf0Spatrick 
248573471bf0Spatrick   return false;
248673471bf0Spatrick }
248773471bf0Spatrick 
ParseIntelMemoryOperandSize(unsigned & Size)248809467b48Spatrick bool X86AsmParser::ParseIntelMemoryOperandSize(unsigned &Size) {
248909467b48Spatrick   Size = StringSwitch<unsigned>(getTok().getString())
249009467b48Spatrick     .Cases("BYTE", "byte", 8)
249109467b48Spatrick     .Cases("WORD", "word", 16)
249209467b48Spatrick     .Cases("DWORD", "dword", 32)
249309467b48Spatrick     .Cases("FLOAT", "float", 32)
249409467b48Spatrick     .Cases("LONG", "long", 32)
249509467b48Spatrick     .Cases("FWORD", "fword", 48)
249609467b48Spatrick     .Cases("DOUBLE", "double", 64)
249709467b48Spatrick     .Cases("QWORD", "qword", 64)
249809467b48Spatrick     .Cases("MMWORD","mmword", 64)
249909467b48Spatrick     .Cases("XWORD", "xword", 80)
250009467b48Spatrick     .Cases("TBYTE", "tbyte", 80)
250109467b48Spatrick     .Cases("XMMWORD", "xmmword", 128)
250209467b48Spatrick     .Cases("YMMWORD", "ymmword", 256)
250309467b48Spatrick     .Cases("ZMMWORD", "zmmword", 512)
250409467b48Spatrick     .Default(0);
250509467b48Spatrick   if (Size) {
250609467b48Spatrick     const AsmToken &Tok = Lex(); // Eat operand size (e.g., byte, word).
250709467b48Spatrick     if (!(Tok.getString().equals("PTR") || Tok.getString().equals("ptr")))
250809467b48Spatrick       return Error(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");
250909467b48Spatrick     Lex(); // Eat ptr.
251009467b48Spatrick   }
251109467b48Spatrick   return false;
251209467b48Spatrick }
251309467b48Spatrick 
parseIntelOperand(OperandVector & Operands,StringRef Name)2514*d415bd75Srobert bool X86AsmParser::parseIntelOperand(OperandVector &Operands, StringRef Name) {
251509467b48Spatrick   MCAsmParser &Parser = getParser();
251609467b48Spatrick   const AsmToken &Tok = Parser.getTok();
251709467b48Spatrick   SMLoc Start, End;
251809467b48Spatrick 
251909467b48Spatrick   // Parse optional Size directive.
252009467b48Spatrick   unsigned Size;
252109467b48Spatrick   if (ParseIntelMemoryOperandSize(Size))
252273471bf0Spatrick     return true;
252309467b48Spatrick   bool PtrInOperand = bool(Size);
252409467b48Spatrick 
252509467b48Spatrick   Start = Tok.getLoc();
252609467b48Spatrick 
252709467b48Spatrick   // Rounding mode operand.
252809467b48Spatrick   if (getLexer().is(AsmToken::LCurly))
252973471bf0Spatrick     return ParseRoundingModeOp(Start, Operands);
253009467b48Spatrick 
253109467b48Spatrick   // Register operand.
2532*d415bd75Srobert   MCRegister RegNo;
2533*d415bd75Srobert   if (Tok.is(AsmToken::Identifier) && !parseRegister(RegNo, Start, End)) {
253409467b48Spatrick     if (RegNo == X86::RIP)
253573471bf0Spatrick       return Error(Start, "rip can only be used as a base register");
253609467b48Spatrick     // A Register followed by ':' is considered a segment override
253773471bf0Spatrick     if (Tok.isNot(AsmToken::Colon)) {
253873471bf0Spatrick       if (PtrInOperand)
253973471bf0Spatrick         return Error(Start, "expected memory operand after 'ptr', "
254009467b48Spatrick                             "found register operand instead");
254173471bf0Spatrick       Operands.push_back(X86Operand::CreateReg(RegNo, Start, End));
254273471bf0Spatrick       return false;
254373471bf0Spatrick     }
254409467b48Spatrick     // An alleged segment override. check if we have a valid segment register
254509467b48Spatrick     if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
254673471bf0Spatrick       return Error(Start, "invalid segment register");
254709467b48Spatrick     // Eat ':' and update Start location
254809467b48Spatrick     Start = Lex().getLoc();
254909467b48Spatrick   }
255009467b48Spatrick 
255109467b48Spatrick   // Immediates and Memory
255209467b48Spatrick   IntelExprStateMachine SM;
255309467b48Spatrick   if (ParseIntelExpression(SM, End))
255473471bf0Spatrick     return true;
255509467b48Spatrick 
2556097a140dSpatrick   if (isParsingMSInlineAsm())
255709467b48Spatrick     RewriteIntelExpression(SM, Start, Tok.getLoc());
255809467b48Spatrick 
255909467b48Spatrick   int64_t Imm = SM.getImm();
256009467b48Spatrick   const MCExpr *Disp = SM.getSym();
256109467b48Spatrick   const MCExpr *ImmDisp = MCConstantExpr::create(Imm, getContext());
256209467b48Spatrick   if (Disp && Imm)
256309467b48Spatrick     Disp = MCBinaryExpr::createAdd(Disp, ImmDisp, getContext());
256409467b48Spatrick   if (!Disp)
256509467b48Spatrick     Disp = ImmDisp;
256609467b48Spatrick 
256709467b48Spatrick   // RegNo != 0 specifies a valid segment register,
256809467b48Spatrick   // and we are parsing a segment override
256909467b48Spatrick   if (!SM.isMemExpr() && !RegNo) {
2570097a140dSpatrick     if (isParsingMSInlineAsm() && SM.isOffsetOperator()) {
257173471bf0Spatrick       const InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
257209467b48Spatrick       if (Info.isKind(InlineAsmIdentifierInfo::IK_Var)) {
257309467b48Spatrick         // Disp includes the address of a variable; make sure this is recorded
257409467b48Spatrick         // for later handling.
257573471bf0Spatrick         Operands.push_back(X86Operand::CreateImm(Disp, Start, End,
257673471bf0Spatrick                                                  SM.getSymName(), Info.Var.Decl,
257773471bf0Spatrick                                                  Info.Var.IsGlobalLV));
257873471bf0Spatrick         return false;
257909467b48Spatrick       }
258009467b48Spatrick     }
258109467b48Spatrick 
258273471bf0Spatrick     Operands.push_back(X86Operand::CreateImm(Disp, Start, End));
258373471bf0Spatrick     return false;
258409467b48Spatrick   }
258509467b48Spatrick 
258609467b48Spatrick   StringRef ErrMsg;
258709467b48Spatrick   unsigned BaseReg = SM.getBaseReg();
258809467b48Spatrick   unsigned IndexReg = SM.getIndexReg();
2589*d415bd75Srobert   if (IndexReg && BaseReg == X86::RIP)
2590*d415bd75Srobert     BaseReg = 0;
259109467b48Spatrick   unsigned Scale = SM.getScale();
259273471bf0Spatrick   if (!PtrInOperand)
259373471bf0Spatrick     Size = SM.getElementSize() << 3;
259409467b48Spatrick 
259509467b48Spatrick   if (Scale == 0 && BaseReg != X86::ESP && BaseReg != X86::RSP &&
259609467b48Spatrick       (IndexReg == X86::ESP || IndexReg == X86::RSP))
259709467b48Spatrick     std::swap(BaseReg, IndexReg);
259809467b48Spatrick 
259909467b48Spatrick   // If BaseReg is a vector register and IndexReg is not, swap them unless
260009467b48Spatrick   // Scale was specified in which case it would be an error.
260109467b48Spatrick   if (Scale == 0 &&
260209467b48Spatrick       !(X86MCRegisterClasses[X86::VR128XRegClassID].contains(IndexReg) ||
260309467b48Spatrick         X86MCRegisterClasses[X86::VR256XRegClassID].contains(IndexReg) ||
260409467b48Spatrick         X86MCRegisterClasses[X86::VR512RegClassID].contains(IndexReg)) &&
260509467b48Spatrick       (X86MCRegisterClasses[X86::VR128XRegClassID].contains(BaseReg) ||
260609467b48Spatrick        X86MCRegisterClasses[X86::VR256XRegClassID].contains(BaseReg) ||
260709467b48Spatrick        X86MCRegisterClasses[X86::VR512RegClassID].contains(BaseReg)))
260809467b48Spatrick     std::swap(BaseReg, IndexReg);
260909467b48Spatrick 
261009467b48Spatrick   if (Scale != 0 &&
261109467b48Spatrick       X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg))
261273471bf0Spatrick     return Error(Start, "16-bit addresses cannot have a scale");
261309467b48Spatrick 
261409467b48Spatrick   // If there was no explicit scale specified, change it to 1.
261509467b48Spatrick   if (Scale == 0)
261609467b48Spatrick     Scale = 1;
261709467b48Spatrick 
261809467b48Spatrick   // If this is a 16-bit addressing mode with the base and index in the wrong
261909467b48Spatrick   // order, swap them so CheckBaseRegAndIndexRegAndScale doesn't fail. It is
262009467b48Spatrick   // shared with att syntax where order matters.
262109467b48Spatrick   if ((BaseReg == X86::SI || BaseReg == X86::DI) &&
262209467b48Spatrick       (IndexReg == X86::BX || IndexReg == X86::BP))
262309467b48Spatrick     std::swap(BaseReg, IndexReg);
262409467b48Spatrick 
262509467b48Spatrick   if ((BaseReg || IndexReg) &&
262609467b48Spatrick       CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, is64BitMode(),
262709467b48Spatrick                                       ErrMsg))
262873471bf0Spatrick     return Error(Start, ErrMsg);
2629097a140dSpatrick   if (isParsingMSInlineAsm())
2630097a140dSpatrick     return CreateMemForMSInlineAsm(RegNo, Disp, BaseReg, IndexReg, Scale, Start,
2631097a140dSpatrick                                    End, Size, SM.getSymName(),
263273471bf0Spatrick                                    SM.getIdentifierInfo(), Operands);
2633097a140dSpatrick 
263473471bf0Spatrick   // When parsing x64 MS-style assembly, all non-absolute references to a named
263573471bf0Spatrick   // variable default to RIP-relative.
2636*d415bd75Srobert   unsigned DefaultBaseReg = X86::NoRegister;
2637*d415bd75Srobert   bool MaybeDirectBranchDest = true;
2638*d415bd75Srobert 
2639*d415bd75Srobert   if (Parser.isParsingMasm()) {
2640*d415bd75Srobert     bool IsUnconditionalBranch =
2641*d415bd75Srobert         Name.equals_insensitive("jmp") || Name.equals_insensitive("call");
2642*d415bd75Srobert     if (is64BitMode() && SM.getElementSize() > 0) {
2643*d415bd75Srobert       DefaultBaseReg = X86::RIP;
2644*d415bd75Srobert     }
2645*d415bd75Srobert     if (IsUnconditionalBranch) {
2646*d415bd75Srobert       if (PtrInOperand) {
2647*d415bd75Srobert         MaybeDirectBranchDest = false;
2648*d415bd75Srobert         if (is64BitMode())
2649*d415bd75Srobert           DefaultBaseReg = X86::RIP;
2650*d415bd75Srobert       } else if (!BaseReg && !IndexReg && Disp &&
2651*d415bd75Srobert                  Disp->getKind() == MCExpr::SymbolRef) {
2652*d415bd75Srobert         if (is64BitMode()) {
2653*d415bd75Srobert           if (SM.getSize() == 8) {
2654*d415bd75Srobert             MaybeDirectBranchDest = false;
2655*d415bd75Srobert             DefaultBaseReg = X86::RIP;
2656*d415bd75Srobert           }
2657*d415bd75Srobert         } else {
2658*d415bd75Srobert           if (SM.getSize() == 4 || SM.getSize() == 2)
2659*d415bd75Srobert             MaybeDirectBranchDest = false;
2660*d415bd75Srobert         }
2661*d415bd75Srobert       }
2662*d415bd75Srobert     }
266309467b48Spatrick   }
266409467b48Spatrick 
2665*d415bd75Srobert   if ((BaseReg || IndexReg || RegNo || DefaultBaseReg != X86::NoRegister))
2666*d415bd75Srobert     Operands.push_back(X86Operand::CreateMem(
2667*d415bd75Srobert         getPointerWidth(), RegNo, Disp, BaseReg, IndexReg, Scale, Start, End,
2668*d415bd75Srobert         Size, DefaultBaseReg, /*SymName=*/StringRef(), /*OpDecl=*/nullptr,
2669*d415bd75Srobert         /*FrontendSize=*/0, /*UseUpRegs=*/false, MaybeDirectBranchDest));
267073471bf0Spatrick   else
2671*d415bd75Srobert     Operands.push_back(X86Operand::CreateMem(
2672*d415bd75Srobert         getPointerWidth(), Disp, Start, End, Size, /*SymName=*/StringRef(),
2673*d415bd75Srobert         /*OpDecl=*/nullptr, /*FrontendSize=*/0, /*UseUpRegs=*/false,
2674*d415bd75Srobert         MaybeDirectBranchDest));
267573471bf0Spatrick   return false;
267673471bf0Spatrick }
267773471bf0Spatrick 
parseATTOperand(OperandVector & Operands)2678*d415bd75Srobert bool X86AsmParser::parseATTOperand(OperandVector &Operands) {
267909467b48Spatrick   MCAsmParser &Parser = getParser();
268009467b48Spatrick   switch (getLexer().getKind()) {
268109467b48Spatrick   case AsmToken::Dollar: {
268209467b48Spatrick     // $42 or $ID -> immediate.
268309467b48Spatrick     SMLoc Start = Parser.getTok().getLoc(), End;
268409467b48Spatrick     Parser.Lex();
268509467b48Spatrick     const MCExpr *Val;
268609467b48Spatrick     // This is an immediate, so we should not parse a register. Do a precheck
268709467b48Spatrick     // for '%' to supercede intra-register parse errors.
268809467b48Spatrick     SMLoc L = Parser.getTok().getLoc();
268909467b48Spatrick     if (check(getLexer().is(AsmToken::Percent), L,
269009467b48Spatrick               "expected immediate expression") ||
269109467b48Spatrick         getParser().parseExpression(Val, End) ||
269209467b48Spatrick         check(isa<X86MCExpr>(Val), L, "expected immediate expression"))
269373471bf0Spatrick       return true;
269473471bf0Spatrick     Operands.push_back(X86Operand::CreateImm(Val, Start, End));
269573471bf0Spatrick     return false;
269609467b48Spatrick   }
269709467b48Spatrick   case AsmToken::LCurly: {
269809467b48Spatrick     SMLoc Start = Parser.getTok().getLoc();
269973471bf0Spatrick     return ParseRoundingModeOp(Start, Operands);
270009467b48Spatrick   }
270109467b48Spatrick   default: {
270209467b48Spatrick     // This a memory operand or a register. We have some parsing complications
270309467b48Spatrick     // as a '(' may be part of an immediate expression or the addressing mode
270409467b48Spatrick     // block. This is complicated by the fact that an assembler-level variable
270509467b48Spatrick     // may refer either to a register or an immediate expression.
270609467b48Spatrick 
270709467b48Spatrick     SMLoc Loc = Parser.getTok().getLoc(), EndLoc;
270809467b48Spatrick     const MCExpr *Expr = nullptr;
270909467b48Spatrick     unsigned Reg = 0;
271009467b48Spatrick     if (getLexer().isNot(AsmToken::LParen)) {
271109467b48Spatrick       // No '(' so this is either a displacement expression or a register.
271209467b48Spatrick       if (Parser.parseExpression(Expr, EndLoc))
271373471bf0Spatrick         return true;
271409467b48Spatrick       if (auto *RE = dyn_cast<X86MCExpr>(Expr)) {
271509467b48Spatrick         // Segment Register. Reset Expr and copy value to register.
271609467b48Spatrick         Expr = nullptr;
271709467b48Spatrick         Reg = RE->getRegNo();
271809467b48Spatrick 
2719*d415bd75Srobert         // Check the register.
272009467b48Spatrick         if (Reg == X86::EIZ || Reg == X86::RIZ)
272173471bf0Spatrick           return Error(
272209467b48Spatrick               Loc, "%eiz and %riz can only be used as index registers",
272309467b48Spatrick               SMRange(Loc, EndLoc));
272409467b48Spatrick         if (Reg == X86::RIP)
272573471bf0Spatrick           return Error(Loc, "%rip can only be used as a base register",
272609467b48Spatrick                        SMRange(Loc, EndLoc));
272709467b48Spatrick         // Return register that are not segment prefixes immediately.
272873471bf0Spatrick         if (!Parser.parseOptionalToken(AsmToken::Colon)) {
272973471bf0Spatrick           Operands.push_back(X86Operand::CreateReg(Reg, Loc, EndLoc));
273073471bf0Spatrick           return false;
273173471bf0Spatrick         }
273209467b48Spatrick         if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(Reg))
273373471bf0Spatrick           return Error(Loc, "invalid segment register");
273473471bf0Spatrick         // Accept a '*' absolute memory reference after the segment. Place it
273573471bf0Spatrick         // before the full memory operand.
273673471bf0Spatrick         if (getLexer().is(AsmToken::Star))
273773471bf0Spatrick           Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
273809467b48Spatrick       }
273909467b48Spatrick     }
274009467b48Spatrick     // This is a Memory operand.
274173471bf0Spatrick     return ParseMemOperand(Reg, Expr, Loc, EndLoc, Operands);
274209467b48Spatrick   }
274309467b48Spatrick   }
274409467b48Spatrick }
274509467b48Spatrick 
274609467b48Spatrick // X86::COND_INVALID if not a recognized condition code or alternate mnemonic,
274709467b48Spatrick // otherwise the EFLAGS Condition Code enumerator.
ParseConditionCode(StringRef CC)274809467b48Spatrick X86::CondCode X86AsmParser::ParseConditionCode(StringRef CC) {
274909467b48Spatrick   return StringSwitch<X86::CondCode>(CC)
275009467b48Spatrick       .Case("o", X86::COND_O)          // Overflow
275109467b48Spatrick       .Case("no", X86::COND_NO)        // No Overflow
275209467b48Spatrick       .Cases("b", "nae", X86::COND_B)  // Below/Neither Above nor Equal
275309467b48Spatrick       .Cases("ae", "nb", X86::COND_AE) // Above or Equal/Not Below
275409467b48Spatrick       .Cases("e", "z", X86::COND_E)    // Equal/Zero
275509467b48Spatrick       .Cases("ne", "nz", X86::COND_NE) // Not Equal/Not Zero
275609467b48Spatrick       .Cases("be", "na", X86::COND_BE) // Below or Equal/Not Above
275709467b48Spatrick       .Cases("a", "nbe", X86::COND_A)  // Above/Neither Below nor Equal
275809467b48Spatrick       .Case("s", X86::COND_S)          // Sign
275909467b48Spatrick       .Case("ns", X86::COND_NS)        // No Sign
276009467b48Spatrick       .Cases("p", "pe", X86::COND_P)   // Parity/Parity Even
276109467b48Spatrick       .Cases("np", "po", X86::COND_NP) // No Parity/Parity Odd
276209467b48Spatrick       .Cases("l", "nge", X86::COND_L)  // Less/Neither Greater nor Equal
276309467b48Spatrick       .Cases("ge", "nl", X86::COND_GE) // Greater or Equal/Not Less
276409467b48Spatrick       .Cases("le", "ng", X86::COND_LE) // Less or Equal/Not Greater
276509467b48Spatrick       .Cases("g", "nle", X86::COND_G)  // Greater/Neither Less nor Equal
276609467b48Spatrick       .Default(X86::COND_INVALID);
276709467b48Spatrick }
276809467b48Spatrick 
276909467b48Spatrick // true on failure, false otherwise
277009467b48Spatrick // If no {z} mark was found - Parser doesn't advance
ParseZ(std::unique_ptr<X86Operand> & Z,const SMLoc & StartLoc)277109467b48Spatrick bool X86AsmParser::ParseZ(std::unique_ptr<X86Operand> &Z,
277209467b48Spatrick                           const SMLoc &StartLoc) {
277309467b48Spatrick   MCAsmParser &Parser = getParser();
277409467b48Spatrick   // Assuming we are just pass the '{' mark, quering the next token
277509467b48Spatrick   // Searched for {z}, but none was found. Return false, as no parsing error was
277609467b48Spatrick   // encountered
277709467b48Spatrick   if (!(getLexer().is(AsmToken::Identifier) &&
277809467b48Spatrick         (getLexer().getTok().getIdentifier() == "z")))
277909467b48Spatrick     return false;
278009467b48Spatrick   Parser.Lex(); // Eat z
278109467b48Spatrick   // Query and eat the '}' mark
278209467b48Spatrick   if (!getLexer().is(AsmToken::RCurly))
278309467b48Spatrick     return Error(getLexer().getLoc(), "Expected } at this point");
278409467b48Spatrick   Parser.Lex(); // Eat '}'
2785*d415bd75Srobert   // Assign Z with the {z} mark operand
278609467b48Spatrick   Z = X86Operand::CreateToken("{z}", StartLoc);
278709467b48Spatrick   return false;
278809467b48Spatrick }
278909467b48Spatrick 
279009467b48Spatrick // true on failure, false otherwise
HandleAVX512Operand(OperandVector & Operands)279173471bf0Spatrick bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands) {
279209467b48Spatrick   MCAsmParser &Parser = getParser();
279309467b48Spatrick   if (getLexer().is(AsmToken::LCurly)) {
279409467b48Spatrick     // Eat "{" and mark the current place.
279509467b48Spatrick     const SMLoc consumedToken = consumeToken();
279609467b48Spatrick     // Distinguish {1to<NUM>} from {%k<NUM>}.
279709467b48Spatrick     if(getLexer().is(AsmToken::Integer)) {
279809467b48Spatrick       // Parse memory broadcasting ({1to<NUM>}).
279909467b48Spatrick       if (getLexer().getTok().getIntVal() != 1)
280009467b48Spatrick         return TokError("Expected 1to<NUM> at this point");
280173471bf0Spatrick       StringRef Prefix = getLexer().getTok().getString();
280273471bf0Spatrick       Parser.Lex(); // Eat first token of 1to8
280373471bf0Spatrick       if (!getLexer().is(AsmToken::Identifier))
280409467b48Spatrick         return TokError("Expected 1to<NUM> at this point");
280509467b48Spatrick       // Recognize only reasonable suffixes.
280673471bf0Spatrick       SmallVector<char, 5> BroadcastVector;
280773471bf0Spatrick       StringRef BroadcastString = (Prefix + getLexer().getTok().getIdentifier())
280873471bf0Spatrick                                       .toStringRef(BroadcastVector);
280973471bf0Spatrick       if (!BroadcastString.startswith("1to"))
281073471bf0Spatrick         return TokError("Expected 1to<NUM> at this point");
281109467b48Spatrick       const char *BroadcastPrimitive =
281273471bf0Spatrick           StringSwitch<const char *>(BroadcastString)
281373471bf0Spatrick               .Case("1to2", "{1to2}")
281473471bf0Spatrick               .Case("1to4", "{1to4}")
281573471bf0Spatrick               .Case("1to8", "{1to8}")
281673471bf0Spatrick               .Case("1to16", "{1to16}")
2817*d415bd75Srobert               .Case("1to32", "{1to32}")
281809467b48Spatrick               .Default(nullptr);
281909467b48Spatrick       if (!BroadcastPrimitive)
282009467b48Spatrick         return TokError("Invalid memory broadcast primitive.");
282173471bf0Spatrick       Parser.Lex(); // Eat trailing token of 1toN
282209467b48Spatrick       if (!getLexer().is(AsmToken::RCurly))
282309467b48Spatrick         return TokError("Expected } at this point");
282409467b48Spatrick       Parser.Lex();  // Eat "}"
282509467b48Spatrick       Operands.push_back(X86Operand::CreateToken(BroadcastPrimitive,
282609467b48Spatrick                                                  consumedToken));
282709467b48Spatrick       // No AVX512 specific primitives can pass
282809467b48Spatrick       // after memory broadcasting, so return.
282909467b48Spatrick       return false;
283009467b48Spatrick     } else {
283109467b48Spatrick       // Parse either {k}{z}, {z}{k}, {k} or {z}
283209467b48Spatrick       // last one have no meaning, but GCC accepts it
283309467b48Spatrick       // Currently, we're just pass a '{' mark
283409467b48Spatrick       std::unique_ptr<X86Operand> Z;
283509467b48Spatrick       if (ParseZ(Z, consumedToken))
283609467b48Spatrick         return true;
283709467b48Spatrick       // Reaching here means that parsing of the allegadly '{z}' mark yielded
283809467b48Spatrick       // no errors.
283909467b48Spatrick       // Query for the need of further parsing for a {%k<NUM>} mark
284009467b48Spatrick       if (!Z || getLexer().is(AsmToken::LCurly)) {
284109467b48Spatrick         SMLoc StartLoc = Z ? consumeToken() : consumedToken;
284209467b48Spatrick         // Parse an op-mask register mark ({%k<NUM>}), which is now to be
284309467b48Spatrick         // expected
2844*d415bd75Srobert         MCRegister RegNo;
284509467b48Spatrick         SMLoc RegLoc;
2846*d415bd75Srobert         if (!parseRegister(RegNo, RegLoc, StartLoc) &&
284709467b48Spatrick             X86MCRegisterClasses[X86::VK1RegClassID].contains(RegNo)) {
284809467b48Spatrick           if (RegNo == X86::K0)
284909467b48Spatrick             return Error(RegLoc, "Register k0 can't be used as write mask");
285009467b48Spatrick           if (!getLexer().is(AsmToken::RCurly))
285109467b48Spatrick             return Error(getLexer().getLoc(), "Expected } at this point");
285209467b48Spatrick           Operands.push_back(X86Operand::CreateToken("{", StartLoc));
285309467b48Spatrick           Operands.push_back(
285409467b48Spatrick               X86Operand::CreateReg(RegNo, StartLoc, StartLoc));
285509467b48Spatrick           Operands.push_back(X86Operand::CreateToken("}", consumeToken()));
285609467b48Spatrick         } else
285709467b48Spatrick           return Error(getLexer().getLoc(),
285809467b48Spatrick                         "Expected an op-mask register at this point");
285909467b48Spatrick         // {%k<NUM>} mark is found, inquire for {z}
286009467b48Spatrick         if (getLexer().is(AsmToken::LCurly) && !Z) {
286109467b48Spatrick           // Have we've found a parsing error, or found no (expected) {z} mark
286209467b48Spatrick           // - report an error
286309467b48Spatrick           if (ParseZ(Z, consumeToken()) || !Z)
286409467b48Spatrick             return Error(getLexer().getLoc(),
286509467b48Spatrick                          "Expected a {z} mark at this point");
286609467b48Spatrick 
286709467b48Spatrick         }
286809467b48Spatrick         // '{z}' on its own is meaningless, hence should be ignored.
286909467b48Spatrick         // on the contrary - have it been accompanied by a K register,
287009467b48Spatrick         // allow it.
287109467b48Spatrick         if (Z)
287209467b48Spatrick           Operands.push_back(std::move(Z));
287309467b48Spatrick       }
287409467b48Spatrick     }
287509467b48Spatrick   }
287609467b48Spatrick   return false;
287709467b48Spatrick }
287809467b48Spatrick 
287909467b48Spatrick /// ParseMemOperand: 'seg : disp(basereg, indexreg, scale)'.  The '%ds:' prefix
288009467b48Spatrick /// has already been parsed if present. disp may be provided as well.
ParseMemOperand(unsigned SegReg,const MCExpr * Disp,SMLoc StartLoc,SMLoc EndLoc,OperandVector & Operands)288173471bf0Spatrick bool X86AsmParser::ParseMemOperand(unsigned SegReg, const MCExpr *Disp,
288273471bf0Spatrick                                    SMLoc StartLoc, SMLoc EndLoc,
288373471bf0Spatrick                                    OperandVector &Operands) {
288409467b48Spatrick   MCAsmParser &Parser = getParser();
288509467b48Spatrick   SMLoc Loc;
288609467b48Spatrick   // Based on the initial passed values, we may be in any of these cases, we are
288709467b48Spatrick   // in one of these cases (with current position (*)):
288809467b48Spatrick 
288909467b48Spatrick   //   1. seg : * disp  (base-index-scale-expr)
289009467b48Spatrick   //   2. seg : *(disp) (base-index-scale-expr)
289109467b48Spatrick   //   3. seg :       *(base-index-scale-expr)
289209467b48Spatrick   //   4.        disp  *(base-index-scale-expr)
289309467b48Spatrick   //   5.      *(disp)  (base-index-scale-expr)
289409467b48Spatrick   //   6.             *(base-index-scale-expr)
289509467b48Spatrick   //   7.  disp *
289609467b48Spatrick   //   8. *(disp)
289709467b48Spatrick 
289809467b48Spatrick   // If we do not have an displacement yet, check if we're in cases 4 or 6 by
289909467b48Spatrick   // checking if the first object after the parenthesis is a register (or an
290009467b48Spatrick   // identifier referring to a register) and parse the displacement or default
290109467b48Spatrick   // to 0 as appropriate.
290209467b48Spatrick   auto isAtMemOperand = [this]() {
290309467b48Spatrick     if (this->getLexer().isNot(AsmToken::LParen))
290409467b48Spatrick       return false;
290509467b48Spatrick     AsmToken Buf[2];
290609467b48Spatrick     StringRef Id;
290709467b48Spatrick     auto TokCount = this->getLexer().peekTokens(Buf, true);
290809467b48Spatrick     if (TokCount == 0)
290909467b48Spatrick       return false;
291009467b48Spatrick     switch (Buf[0].getKind()) {
291109467b48Spatrick     case AsmToken::Percent:
291209467b48Spatrick     case AsmToken::Comma:
291309467b48Spatrick       return true;
291409467b48Spatrick     // These lower cases are doing a peekIdentifier.
291509467b48Spatrick     case AsmToken::At:
291609467b48Spatrick     case AsmToken::Dollar:
291709467b48Spatrick       if ((TokCount > 1) &&
291809467b48Spatrick           (Buf[1].is(AsmToken::Identifier) || Buf[1].is(AsmToken::String)) &&
291909467b48Spatrick           (Buf[0].getLoc().getPointer() + 1 == Buf[1].getLoc().getPointer()))
292009467b48Spatrick         Id = StringRef(Buf[0].getLoc().getPointer(),
292109467b48Spatrick                        Buf[1].getIdentifier().size() + 1);
292209467b48Spatrick       break;
292309467b48Spatrick     case AsmToken::Identifier:
292409467b48Spatrick     case AsmToken::String:
292509467b48Spatrick       Id = Buf[0].getIdentifier();
292609467b48Spatrick       break;
292709467b48Spatrick     default:
292809467b48Spatrick       return false;
292909467b48Spatrick     }
293009467b48Spatrick     // We have an ID. Check if it is bound to a register.
293109467b48Spatrick     if (!Id.empty()) {
293209467b48Spatrick       MCSymbol *Sym = this->getContext().getOrCreateSymbol(Id);
293309467b48Spatrick       if (Sym->isVariable()) {
293409467b48Spatrick         auto V = Sym->getVariableValue(/*SetUsed*/ false);
293509467b48Spatrick         return isa<X86MCExpr>(V);
293609467b48Spatrick       }
293709467b48Spatrick     }
293809467b48Spatrick     return false;
293909467b48Spatrick   };
294009467b48Spatrick 
294109467b48Spatrick   if (!Disp) {
294209467b48Spatrick     // Parse immediate if we're not at a mem operand yet.
294309467b48Spatrick     if (!isAtMemOperand()) {
294409467b48Spatrick       if (Parser.parseTokenLoc(Loc) || Parser.parseExpression(Disp, EndLoc))
294573471bf0Spatrick         return true;
294609467b48Spatrick       assert(!isa<X86MCExpr>(Disp) && "Expected non-register here.");
294709467b48Spatrick     } else {
294809467b48Spatrick       // Disp is implicitly zero if we haven't parsed it yet.
294909467b48Spatrick       Disp = MCConstantExpr::create(0, Parser.getContext());
295009467b48Spatrick     }
295109467b48Spatrick   }
295209467b48Spatrick 
295309467b48Spatrick   // We are now either at the end of the operand or at the '(' at the start of a
295409467b48Spatrick   // base-index-scale-expr.
295509467b48Spatrick 
295609467b48Spatrick   if (!parseOptionalToken(AsmToken::LParen)) {
295709467b48Spatrick     if (SegReg == 0)
295873471bf0Spatrick       Operands.push_back(
295973471bf0Spatrick           X86Operand::CreateMem(getPointerWidth(), Disp, StartLoc, EndLoc));
296073471bf0Spatrick     else
296173471bf0Spatrick       Operands.push_back(X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,
296273471bf0Spatrick                                                0, 0, 1, StartLoc, EndLoc));
296373471bf0Spatrick     return false;
296409467b48Spatrick   }
296509467b48Spatrick 
296609467b48Spatrick   // If we reached here, then eat the '(' and Process
296709467b48Spatrick   // the rest of the memory operand.
296809467b48Spatrick   unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
296909467b48Spatrick   SMLoc BaseLoc = getLexer().getLoc();
297009467b48Spatrick   const MCExpr *E;
297109467b48Spatrick   StringRef ErrMsg;
297209467b48Spatrick 
297309467b48Spatrick   // Parse BaseReg if one is provided.
297409467b48Spatrick   if (getLexer().isNot(AsmToken::Comma) && getLexer().isNot(AsmToken::RParen)) {
297509467b48Spatrick     if (Parser.parseExpression(E, EndLoc) ||
297609467b48Spatrick         check(!isa<X86MCExpr>(E), BaseLoc, "expected register here"))
297773471bf0Spatrick       return true;
297809467b48Spatrick 
2979*d415bd75Srobert     // Check the register.
298009467b48Spatrick     BaseReg = cast<X86MCExpr>(E)->getRegNo();
298109467b48Spatrick     if (BaseReg == X86::EIZ || BaseReg == X86::RIZ)
298273471bf0Spatrick       return Error(BaseLoc, "eiz and riz can only be used as index registers",
298309467b48Spatrick                    SMRange(BaseLoc, EndLoc));
298409467b48Spatrick   }
298509467b48Spatrick 
298609467b48Spatrick   if (parseOptionalToken(AsmToken::Comma)) {
298709467b48Spatrick     // Following the comma we should have either an index register, or a scale
298809467b48Spatrick     // value. We don't support the later form, but we want to parse it
298909467b48Spatrick     // correctly.
299009467b48Spatrick     //
299109467b48Spatrick     // Even though it would be completely consistent to support syntax like
299209467b48Spatrick     // "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
299309467b48Spatrick     if (getLexer().isNot(AsmToken::RParen)) {
299409467b48Spatrick       if (Parser.parseTokenLoc(Loc) || Parser.parseExpression(E, EndLoc))
299573471bf0Spatrick         return true;
299609467b48Spatrick 
299709467b48Spatrick       if (!isa<X86MCExpr>(E)) {
299809467b48Spatrick         // We've parsed an unexpected Scale Value instead of an index
299909467b48Spatrick         // register. Interpret it as an absolute.
300009467b48Spatrick         int64_t ScaleVal;
300109467b48Spatrick         if (!E->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr()))
300273471bf0Spatrick           return Error(Loc, "expected absolute expression");
300309467b48Spatrick         if (ScaleVal != 1)
300409467b48Spatrick           Warning(Loc, "scale factor without index register is ignored");
300509467b48Spatrick         Scale = 1;
300609467b48Spatrick       } else { // IndexReg Found.
300709467b48Spatrick         IndexReg = cast<X86MCExpr>(E)->getRegNo();
300809467b48Spatrick 
300909467b48Spatrick         if (BaseReg == X86::RIP)
301073471bf0Spatrick           return Error(Loc,
301173471bf0Spatrick                        "%rip as base register can not have an index register");
301209467b48Spatrick         if (IndexReg == X86::RIP)
301373471bf0Spatrick           return Error(Loc, "%rip is not allowed as an index register");
301409467b48Spatrick 
301509467b48Spatrick         if (parseOptionalToken(AsmToken::Comma)) {
301609467b48Spatrick           // Parse the scale amount:
301709467b48Spatrick           //  ::= ',' [scale-expression]
301809467b48Spatrick 
301909467b48Spatrick           // A scale amount without an index is ignored.
302009467b48Spatrick           if (getLexer().isNot(AsmToken::RParen)) {
302109467b48Spatrick             int64_t ScaleVal;
302209467b48Spatrick             if (Parser.parseTokenLoc(Loc) ||
302309467b48Spatrick                 Parser.parseAbsoluteExpression(ScaleVal))
302473471bf0Spatrick               return Error(Loc, "expected scale expression");
302509467b48Spatrick             Scale = (unsigned)ScaleVal;
302609467b48Spatrick             // Validate the scale amount.
302709467b48Spatrick             if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
302809467b48Spatrick                 Scale != 1)
302973471bf0Spatrick               return Error(Loc, "scale factor in 16-bit address must be 1");
303009467b48Spatrick             if (checkScale(Scale, ErrMsg))
303173471bf0Spatrick               return Error(Loc, ErrMsg);
303209467b48Spatrick           }
303309467b48Spatrick         }
303409467b48Spatrick       }
303509467b48Spatrick     }
303609467b48Spatrick   }
303709467b48Spatrick 
303809467b48Spatrick   // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
303909467b48Spatrick   if (parseToken(AsmToken::RParen, "unexpected token in memory operand"))
304073471bf0Spatrick     return true;
304109467b48Spatrick 
304209467b48Spatrick   // This is to support otherwise illegal operand (%dx) found in various
304309467b48Spatrick   // unofficial manuals examples (e.g. "out[s]?[bwl]? %al, (%dx)") and must now
304409467b48Spatrick   // be supported. Mark such DX variants separately fix only in special cases.
304509467b48Spatrick   if (BaseReg == X86::DX && IndexReg == 0 && Scale == 1 && SegReg == 0 &&
304673471bf0Spatrick       isa<MCConstantExpr>(Disp) &&
304773471bf0Spatrick       cast<MCConstantExpr>(Disp)->getValue() == 0) {
304873471bf0Spatrick     Operands.push_back(X86Operand::CreateDXReg(BaseLoc, BaseLoc));
304973471bf0Spatrick     return false;
305073471bf0Spatrick   }
305109467b48Spatrick 
305209467b48Spatrick   if (CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, is64BitMode(),
305309467b48Spatrick                                       ErrMsg))
305473471bf0Spatrick     return Error(BaseLoc, ErrMsg);
305509467b48Spatrick 
305609467b48Spatrick   if (SegReg || BaseReg || IndexReg)
305773471bf0Spatrick     Operands.push_back(X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,
305873471bf0Spatrick                                              BaseReg, IndexReg, Scale, StartLoc,
305973471bf0Spatrick                                              EndLoc));
306073471bf0Spatrick   else
306173471bf0Spatrick     Operands.push_back(
306273471bf0Spatrick         X86Operand::CreateMem(getPointerWidth(), Disp, StartLoc, EndLoc));
306373471bf0Spatrick   return false;
306409467b48Spatrick }
306509467b48Spatrick 
306609467b48Spatrick // Parse either a standard primary expression or a register.
parsePrimaryExpr(const MCExpr * & Res,SMLoc & EndLoc)306709467b48Spatrick bool X86AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
306809467b48Spatrick   MCAsmParser &Parser = getParser();
306909467b48Spatrick   // See if this is a register first.
307009467b48Spatrick   if (getTok().is(AsmToken::Percent) ||
307109467b48Spatrick       (isParsingIntelSyntax() && getTok().is(AsmToken::Identifier) &&
307209467b48Spatrick        MatchRegisterName(Parser.getTok().getString()))) {
307309467b48Spatrick     SMLoc StartLoc = Parser.getTok().getLoc();
3074*d415bd75Srobert     MCRegister RegNo;
3075*d415bd75Srobert     if (parseRegister(RegNo, StartLoc, EndLoc))
307609467b48Spatrick       return true;
307709467b48Spatrick     Res = X86MCExpr::create(RegNo, Parser.getContext());
307809467b48Spatrick     return false;
307909467b48Spatrick   }
308073471bf0Spatrick   return Parser.parsePrimaryExpr(Res, EndLoc, nullptr);
308109467b48Spatrick }
308209467b48Spatrick 
ParseInstruction(ParseInstructionInfo & Info,StringRef Name,SMLoc NameLoc,OperandVector & Operands)308309467b48Spatrick bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
308409467b48Spatrick                                     SMLoc NameLoc, OperandVector &Operands) {
308509467b48Spatrick   MCAsmParser &Parser = getParser();
308609467b48Spatrick   InstInfo = &Info;
308709467b48Spatrick 
308809467b48Spatrick   // Reset the forced VEX encoding.
308909467b48Spatrick   ForcedVEXEncoding = VEXEncoding_Default;
309073471bf0Spatrick   ForcedDispEncoding = DispEncoding_Default;
309109467b48Spatrick 
309209467b48Spatrick   // Parse pseudo prefixes.
3093*d415bd75Srobert   while (true) {
309409467b48Spatrick     if (Name == "{") {
309509467b48Spatrick       if (getLexer().isNot(AsmToken::Identifier))
309609467b48Spatrick         return Error(Parser.getTok().getLoc(), "Unexpected token after '{'");
309709467b48Spatrick       std::string Prefix = Parser.getTok().getString().lower();
309809467b48Spatrick       Parser.Lex(); // Eat identifier.
309909467b48Spatrick       if (getLexer().isNot(AsmToken::RCurly))
310009467b48Spatrick         return Error(Parser.getTok().getLoc(), "Expected '}'");
310109467b48Spatrick       Parser.Lex(); // Eat curly.
310209467b48Spatrick 
310373471bf0Spatrick       if (Prefix == "vex")
3104097a140dSpatrick         ForcedVEXEncoding = VEXEncoding_VEX;
310573471bf0Spatrick       else if (Prefix == "vex2")
310673471bf0Spatrick         ForcedVEXEncoding = VEXEncoding_VEX2;
310709467b48Spatrick       else if (Prefix == "vex3")
310809467b48Spatrick         ForcedVEXEncoding = VEXEncoding_VEX3;
310909467b48Spatrick       else if (Prefix == "evex")
311009467b48Spatrick         ForcedVEXEncoding = VEXEncoding_EVEX;
311173471bf0Spatrick       else if (Prefix == "disp8")
311273471bf0Spatrick         ForcedDispEncoding = DispEncoding_Disp8;
311373471bf0Spatrick       else if (Prefix == "disp32")
311473471bf0Spatrick         ForcedDispEncoding = DispEncoding_Disp32;
311509467b48Spatrick       else
311609467b48Spatrick         return Error(NameLoc, "unknown prefix");
311709467b48Spatrick 
311809467b48Spatrick       NameLoc = Parser.getTok().getLoc();
311909467b48Spatrick       if (getLexer().is(AsmToken::LCurly)) {
312009467b48Spatrick         Parser.Lex();
312109467b48Spatrick         Name = "{";
312209467b48Spatrick       } else {
312309467b48Spatrick         if (getLexer().isNot(AsmToken::Identifier))
312409467b48Spatrick           return Error(Parser.getTok().getLoc(), "Expected identifier");
312509467b48Spatrick         // FIXME: The mnemonic won't match correctly if its not in lower case.
312609467b48Spatrick         Name = Parser.getTok().getString();
312709467b48Spatrick         Parser.Lex();
312809467b48Spatrick       }
312909467b48Spatrick       continue;
313009467b48Spatrick     }
313173471bf0Spatrick     // Parse MASM style pseudo prefixes.
313273471bf0Spatrick     if (isParsingMSInlineAsm()) {
313373471bf0Spatrick       if (Name.equals_insensitive("vex"))
313473471bf0Spatrick         ForcedVEXEncoding = VEXEncoding_VEX;
313573471bf0Spatrick       else if (Name.equals_insensitive("vex2"))
313673471bf0Spatrick         ForcedVEXEncoding = VEXEncoding_VEX2;
313773471bf0Spatrick       else if (Name.equals_insensitive("vex3"))
313873471bf0Spatrick         ForcedVEXEncoding = VEXEncoding_VEX3;
313973471bf0Spatrick       else if (Name.equals_insensitive("evex"))
314073471bf0Spatrick         ForcedVEXEncoding = VEXEncoding_EVEX;
314109467b48Spatrick 
314273471bf0Spatrick       if (ForcedVEXEncoding != VEXEncoding_Default) {
314373471bf0Spatrick         if (getLexer().isNot(AsmToken::Identifier))
314473471bf0Spatrick           return Error(Parser.getTok().getLoc(), "Expected identifier");
314573471bf0Spatrick         // FIXME: The mnemonic won't match correctly if its not in lower case.
314673471bf0Spatrick         Name = Parser.getTok().getString();
314773471bf0Spatrick         NameLoc = Parser.getTok().getLoc();
314873471bf0Spatrick         Parser.Lex();
314973471bf0Spatrick       }
315073471bf0Spatrick     }
315109467b48Spatrick     break;
315209467b48Spatrick   }
315309467b48Spatrick 
315473471bf0Spatrick   // Support the suffix syntax for overriding displacement size as well.
315573471bf0Spatrick   if (Name.consume_back(".d32")) {
315673471bf0Spatrick     ForcedDispEncoding = DispEncoding_Disp32;
315773471bf0Spatrick   } else if (Name.consume_back(".d8")) {
315873471bf0Spatrick     ForcedDispEncoding = DispEncoding_Disp8;
315973471bf0Spatrick   }
316073471bf0Spatrick 
316109467b48Spatrick   StringRef PatchedName = Name;
316209467b48Spatrick 
316309467b48Spatrick   // Hack to skip "short" following Jcc.
316409467b48Spatrick   if (isParsingIntelSyntax() &&
316509467b48Spatrick       (PatchedName == "jmp" || PatchedName == "jc" || PatchedName == "jnc" ||
316673471bf0Spatrick        PatchedName == "jcxz" || PatchedName == "jecxz" ||
316709467b48Spatrick        (PatchedName.startswith("j") &&
316809467b48Spatrick         ParseConditionCode(PatchedName.substr(1)) != X86::COND_INVALID))) {
316909467b48Spatrick     StringRef NextTok = Parser.getTok().getString();
317073471bf0Spatrick     if (Parser.isParsingMasm() ? NextTok.equals_insensitive("short")
317173471bf0Spatrick                                : NextTok == "short") {
317209467b48Spatrick       SMLoc NameEndLoc =
317309467b48Spatrick           NameLoc.getFromPointer(NameLoc.getPointer() + Name.size());
317409467b48Spatrick       // Eat the short keyword.
317509467b48Spatrick       Parser.Lex();
317609467b48Spatrick       // MS and GAS ignore the short keyword; they both determine the jmp type
317709467b48Spatrick       // based on the distance of the label. (NASM does emit different code with
317809467b48Spatrick       // and without "short," though.)
317909467b48Spatrick       InstInfo->AsmRewrites->emplace_back(AOK_Skip, NameEndLoc,
318009467b48Spatrick                                           NextTok.size() + 1);
318109467b48Spatrick     }
318209467b48Spatrick   }
318309467b48Spatrick 
318409467b48Spatrick   // FIXME: Hack to recognize setneb as setne.
318509467b48Spatrick   if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
318609467b48Spatrick       PatchedName != "setb" && PatchedName != "setnb")
318709467b48Spatrick     PatchedName = PatchedName.substr(0, Name.size()-1);
318809467b48Spatrick 
318909467b48Spatrick   unsigned ComparisonPredicate = ~0U;
319009467b48Spatrick 
3191*d415bd75Srobert   // FIXME: Hack to recognize cmp<comparison code>{sh,ss,sd,ph,ps,pd}.
319209467b48Spatrick   if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
319309467b48Spatrick       (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
3194*d415bd75Srobert        PatchedName.endswith("sh") || PatchedName.endswith("ph") ||
319509467b48Spatrick        PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
319609467b48Spatrick     bool IsVCMP = PatchedName[0] == 'v';
319709467b48Spatrick     unsigned CCIdx = IsVCMP ? 4 : 3;
319809467b48Spatrick     unsigned CC = StringSwitch<unsigned>(
319909467b48Spatrick       PatchedName.slice(CCIdx, PatchedName.size() - 2))
320009467b48Spatrick       .Case("eq",       0x00)
320109467b48Spatrick       .Case("eq_oq",    0x00)
320209467b48Spatrick       .Case("lt",       0x01)
320309467b48Spatrick       .Case("lt_os",    0x01)
320409467b48Spatrick       .Case("le",       0x02)
320509467b48Spatrick       .Case("le_os",    0x02)
320609467b48Spatrick       .Case("unord",    0x03)
320709467b48Spatrick       .Case("unord_q",  0x03)
320809467b48Spatrick       .Case("neq",      0x04)
320909467b48Spatrick       .Case("neq_uq",   0x04)
321009467b48Spatrick       .Case("nlt",      0x05)
321109467b48Spatrick       .Case("nlt_us",   0x05)
321209467b48Spatrick       .Case("nle",      0x06)
321309467b48Spatrick       .Case("nle_us",   0x06)
321409467b48Spatrick       .Case("ord",      0x07)
321509467b48Spatrick       .Case("ord_q",    0x07)
321609467b48Spatrick       /* AVX only from here */
321709467b48Spatrick       .Case("eq_uq",    0x08)
321809467b48Spatrick       .Case("nge",      0x09)
321909467b48Spatrick       .Case("nge_us",   0x09)
322009467b48Spatrick       .Case("ngt",      0x0A)
322109467b48Spatrick       .Case("ngt_us",   0x0A)
322209467b48Spatrick       .Case("false",    0x0B)
322309467b48Spatrick       .Case("false_oq", 0x0B)
322409467b48Spatrick       .Case("neq_oq",   0x0C)
322509467b48Spatrick       .Case("ge",       0x0D)
322609467b48Spatrick       .Case("ge_os",    0x0D)
322709467b48Spatrick       .Case("gt",       0x0E)
322809467b48Spatrick       .Case("gt_os",    0x0E)
322909467b48Spatrick       .Case("true",     0x0F)
323009467b48Spatrick       .Case("true_uq",  0x0F)
323109467b48Spatrick       .Case("eq_os",    0x10)
323209467b48Spatrick       .Case("lt_oq",    0x11)
323309467b48Spatrick       .Case("le_oq",    0x12)
323409467b48Spatrick       .Case("unord_s",  0x13)
323509467b48Spatrick       .Case("neq_us",   0x14)
323609467b48Spatrick       .Case("nlt_uq",   0x15)
323709467b48Spatrick       .Case("nle_uq",   0x16)
323809467b48Spatrick       .Case("ord_s",    0x17)
323909467b48Spatrick       .Case("eq_us",    0x18)
324009467b48Spatrick       .Case("nge_uq",   0x19)
324109467b48Spatrick       .Case("ngt_uq",   0x1A)
324209467b48Spatrick       .Case("false_os", 0x1B)
324309467b48Spatrick       .Case("neq_os",   0x1C)
324409467b48Spatrick       .Case("ge_oq",    0x1D)
324509467b48Spatrick       .Case("gt_oq",    0x1E)
324609467b48Spatrick       .Case("true_us",  0x1F)
324709467b48Spatrick       .Default(~0U);
3248*d415bd75Srobert     if (CC != ~0U && (IsVCMP || CC < 8) &&
3249*d415bd75Srobert         (IsVCMP || PatchedName.back() != 'h')) {
325009467b48Spatrick       if (PatchedName.endswith("ss"))
325109467b48Spatrick         PatchedName = IsVCMP ? "vcmpss" : "cmpss";
325209467b48Spatrick       else if (PatchedName.endswith("sd"))
325309467b48Spatrick         PatchedName = IsVCMP ? "vcmpsd" : "cmpsd";
325409467b48Spatrick       else if (PatchedName.endswith("ps"))
325509467b48Spatrick         PatchedName = IsVCMP ? "vcmpps" : "cmpps";
325609467b48Spatrick       else if (PatchedName.endswith("pd"))
325709467b48Spatrick         PatchedName = IsVCMP ? "vcmppd" : "cmppd";
3258*d415bd75Srobert       else if (PatchedName.endswith("sh"))
3259*d415bd75Srobert         PatchedName = "vcmpsh";
3260*d415bd75Srobert       else if (PatchedName.endswith("ph"))
3261*d415bd75Srobert         PatchedName = "vcmpph";
326209467b48Spatrick       else
326309467b48Spatrick         llvm_unreachable("Unexpected suffix!");
326409467b48Spatrick 
326509467b48Spatrick       ComparisonPredicate = CC;
326609467b48Spatrick     }
326709467b48Spatrick   }
326809467b48Spatrick 
326909467b48Spatrick   // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}.
327009467b48Spatrick   if (PatchedName.startswith("vpcmp") &&
327109467b48Spatrick       (PatchedName.back() == 'b' || PatchedName.back() == 'w' ||
327209467b48Spatrick        PatchedName.back() == 'd' || PatchedName.back() == 'q')) {
327309467b48Spatrick     unsigned SuffixSize = PatchedName.drop_back().back() == 'u' ? 2 : 1;
327409467b48Spatrick     unsigned CC = StringSwitch<unsigned>(
327509467b48Spatrick       PatchedName.slice(5, PatchedName.size() - SuffixSize))
327609467b48Spatrick       .Case("eq",    0x0) // Only allowed on unsigned. Checked below.
327709467b48Spatrick       .Case("lt",    0x1)
327809467b48Spatrick       .Case("le",    0x2)
327909467b48Spatrick       //.Case("false", 0x3) // Not a documented alias.
328009467b48Spatrick       .Case("neq",   0x4)
328109467b48Spatrick       .Case("nlt",   0x5)
328209467b48Spatrick       .Case("nle",   0x6)
328309467b48Spatrick       //.Case("true",  0x7) // Not a documented alias.
328409467b48Spatrick       .Default(~0U);
328509467b48Spatrick     if (CC != ~0U && (CC != 0 || SuffixSize == 2)) {
328609467b48Spatrick       switch (PatchedName.back()) {
328709467b48Spatrick       default: llvm_unreachable("Unexpected character!");
328809467b48Spatrick       case 'b': PatchedName = SuffixSize == 2 ? "vpcmpub" : "vpcmpb"; break;
328909467b48Spatrick       case 'w': PatchedName = SuffixSize == 2 ? "vpcmpuw" : "vpcmpw"; break;
329009467b48Spatrick       case 'd': PatchedName = SuffixSize == 2 ? "vpcmpud" : "vpcmpd"; break;
329109467b48Spatrick       case 'q': PatchedName = SuffixSize == 2 ? "vpcmpuq" : "vpcmpq"; break;
329209467b48Spatrick       }
329309467b48Spatrick       // Set up the immediate to push into the operands later.
329409467b48Spatrick       ComparisonPredicate = CC;
329509467b48Spatrick     }
329609467b48Spatrick   }
329709467b48Spatrick 
329809467b48Spatrick   // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}.
329909467b48Spatrick   if (PatchedName.startswith("vpcom") &&
330009467b48Spatrick       (PatchedName.back() == 'b' || PatchedName.back() == 'w' ||
330109467b48Spatrick        PatchedName.back() == 'd' || PatchedName.back() == 'q')) {
330209467b48Spatrick     unsigned SuffixSize = PatchedName.drop_back().back() == 'u' ? 2 : 1;
330309467b48Spatrick     unsigned CC = StringSwitch<unsigned>(
330409467b48Spatrick       PatchedName.slice(5, PatchedName.size() - SuffixSize))
330509467b48Spatrick       .Case("lt",    0x0)
330609467b48Spatrick       .Case("le",    0x1)
330709467b48Spatrick       .Case("gt",    0x2)
330809467b48Spatrick       .Case("ge",    0x3)
330909467b48Spatrick       .Case("eq",    0x4)
331009467b48Spatrick       .Case("neq",   0x5)
331109467b48Spatrick       .Case("false", 0x6)
331209467b48Spatrick       .Case("true",  0x7)
331309467b48Spatrick       .Default(~0U);
331409467b48Spatrick     if (CC != ~0U) {
331509467b48Spatrick       switch (PatchedName.back()) {
331609467b48Spatrick       default: llvm_unreachable("Unexpected character!");
331709467b48Spatrick       case 'b': PatchedName = SuffixSize == 2 ? "vpcomub" : "vpcomb"; break;
331809467b48Spatrick       case 'w': PatchedName = SuffixSize == 2 ? "vpcomuw" : "vpcomw"; break;
331909467b48Spatrick       case 'd': PatchedName = SuffixSize == 2 ? "vpcomud" : "vpcomd"; break;
332009467b48Spatrick       case 'q': PatchedName = SuffixSize == 2 ? "vpcomuq" : "vpcomq"; break;
332109467b48Spatrick       }
332209467b48Spatrick       // Set up the immediate to push into the operands later.
332309467b48Spatrick       ComparisonPredicate = CC;
332409467b48Spatrick     }
332509467b48Spatrick   }
332609467b48Spatrick 
332709467b48Spatrick 
332809467b48Spatrick   // Determine whether this is an instruction prefix.
332909467b48Spatrick   // FIXME:
333009467b48Spatrick   // Enhance prefixes integrity robustness. for example, following forms
333109467b48Spatrick   // are currently tolerated:
333209467b48Spatrick   // repz repnz <insn>    ; GAS errors for the use of two similar prefixes
333309467b48Spatrick   // lock addq %rax, %rbx ; Destination operand must be of memory type
333409467b48Spatrick   // xacquire <insn>      ; xacquire must be accompanied by 'lock'
333573471bf0Spatrick   bool IsPrefix =
333673471bf0Spatrick       StringSwitch<bool>(Name)
333773471bf0Spatrick           .Cases("cs", "ds", "es", "fs", "gs", "ss", true)
333873471bf0Spatrick           .Cases("rex64", "data32", "data16", "addr32", "addr16", true)
333909467b48Spatrick           .Cases("xacquire", "xrelease", true)
334009467b48Spatrick           .Cases("acquire", "release", isParsingIntelSyntax())
334109467b48Spatrick           .Default(false);
334209467b48Spatrick 
334309467b48Spatrick   auto isLockRepeatNtPrefix = [](StringRef N) {
334409467b48Spatrick     return StringSwitch<bool>(N)
334509467b48Spatrick         .Cases("lock", "rep", "repe", "repz", "repne", "repnz", "notrack", true)
334609467b48Spatrick         .Default(false);
334709467b48Spatrick   };
334809467b48Spatrick 
334909467b48Spatrick   bool CurlyAsEndOfStatement = false;
335009467b48Spatrick 
335109467b48Spatrick   unsigned Flags = X86::IP_NO_PREFIX;
335209467b48Spatrick   while (isLockRepeatNtPrefix(Name.lower())) {
335309467b48Spatrick     unsigned Prefix =
335409467b48Spatrick         StringSwitch<unsigned>(Name)
335509467b48Spatrick             .Cases("lock", "lock", X86::IP_HAS_LOCK)
335609467b48Spatrick             .Cases("rep", "repe", "repz", X86::IP_HAS_REPEAT)
335709467b48Spatrick             .Cases("repne", "repnz", X86::IP_HAS_REPEAT_NE)
335809467b48Spatrick             .Cases("notrack", "notrack", X86::IP_HAS_NOTRACK)
335909467b48Spatrick             .Default(X86::IP_NO_PREFIX); // Invalid prefix (impossible)
336009467b48Spatrick     Flags |= Prefix;
336109467b48Spatrick     if (getLexer().is(AsmToken::EndOfStatement)) {
336209467b48Spatrick       // We don't have real instr with the given prefix
336309467b48Spatrick       //  let's use the prefix as the instr.
336409467b48Spatrick       // TODO: there could be several prefixes one after another
336509467b48Spatrick       Flags = X86::IP_NO_PREFIX;
336609467b48Spatrick       break;
336709467b48Spatrick     }
336809467b48Spatrick     // FIXME: The mnemonic won't match correctly if its not in lower case.
336909467b48Spatrick     Name = Parser.getTok().getString();
337009467b48Spatrick     Parser.Lex(); // eat the prefix
337109467b48Spatrick     // Hack: we could have something like "rep # some comment" or
337209467b48Spatrick     //    "lock; cmpxchg16b $1" or "lock\0A\09incl" or "lock/incl"
337309467b48Spatrick     while (Name.startswith(";") || Name.startswith("\n") ||
337409467b48Spatrick            Name.startswith("#") || Name.startswith("\t") ||
337509467b48Spatrick            Name.startswith("/")) {
337609467b48Spatrick       // FIXME: The mnemonic won't match correctly if its not in lower case.
337709467b48Spatrick       Name = Parser.getTok().getString();
337809467b48Spatrick       Parser.Lex(); // go to next prefix or instr
337909467b48Spatrick     }
338009467b48Spatrick   }
338109467b48Spatrick 
338209467b48Spatrick   if (Flags)
338309467b48Spatrick     PatchedName = Name;
338409467b48Spatrick 
338509467b48Spatrick   // Hacks to handle 'data16' and 'data32'
338609467b48Spatrick   if (PatchedName == "data16" && is16BitMode()) {
338709467b48Spatrick     return Error(NameLoc, "redundant data16 prefix");
338809467b48Spatrick   }
338909467b48Spatrick   if (PatchedName == "data32") {
339009467b48Spatrick     if (is32BitMode())
339109467b48Spatrick       return Error(NameLoc, "redundant data32 prefix");
339209467b48Spatrick     if (is64BitMode())
339309467b48Spatrick       return Error(NameLoc, "'data32' is not supported in 64-bit mode");
339409467b48Spatrick     // Hack to 'data16' for the table lookup.
339509467b48Spatrick     PatchedName = "data16";
339673471bf0Spatrick 
339773471bf0Spatrick     if (getLexer().isNot(AsmToken::EndOfStatement)) {
339873471bf0Spatrick       StringRef Next = Parser.getTok().getString();
339973471bf0Spatrick       getLexer().Lex();
340073471bf0Spatrick       // data32 effectively changes the instruction suffix.
340173471bf0Spatrick       // TODO Generalize.
340273471bf0Spatrick       if (Next == "callw")
340373471bf0Spatrick         Next = "calll";
340473471bf0Spatrick       if (Next == "ljmpw")
340573471bf0Spatrick         Next = "ljmpl";
340673471bf0Spatrick 
340773471bf0Spatrick       Name = Next;
340873471bf0Spatrick       PatchedName = Name;
3409*d415bd75Srobert       ForcedDataPrefix = X86::Is32Bit;
341073471bf0Spatrick       IsPrefix = false;
341173471bf0Spatrick     }
341209467b48Spatrick   }
341309467b48Spatrick 
341409467b48Spatrick   Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
341509467b48Spatrick 
341609467b48Spatrick   // Push the immediate if we extracted one from the mnemonic.
341709467b48Spatrick   if (ComparisonPredicate != ~0U && !isParsingIntelSyntax()) {
341809467b48Spatrick     const MCExpr *ImmOp = MCConstantExpr::create(ComparisonPredicate,
341909467b48Spatrick                                                  getParser().getContext());
342009467b48Spatrick     Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
342109467b48Spatrick   }
342209467b48Spatrick 
342309467b48Spatrick   // This does the actual operand parsing.  Don't parse any more if we have a
342409467b48Spatrick   // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
342509467b48Spatrick   // just want to parse the "lock" as the first instruction and the "incl" as
342609467b48Spatrick   // the next one.
342773471bf0Spatrick   if (getLexer().isNot(AsmToken::EndOfStatement) && !IsPrefix) {
342809467b48Spatrick     // Parse '*' modifier.
342909467b48Spatrick     if (getLexer().is(AsmToken::Star))
343009467b48Spatrick       Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
343109467b48Spatrick 
343209467b48Spatrick     // Read the operands.
3433*d415bd75Srobert     while (true) {
3434*d415bd75Srobert       if (parseOperand(Operands, Name))
343509467b48Spatrick         return true;
343673471bf0Spatrick       if (HandleAVX512Operand(Operands))
343709467b48Spatrick         return true;
343873471bf0Spatrick 
343909467b48Spatrick       // check for comma and eat it
344009467b48Spatrick       if (getLexer().is(AsmToken::Comma))
344109467b48Spatrick         Parser.Lex();
344209467b48Spatrick       else
344309467b48Spatrick         break;
344409467b48Spatrick      }
344509467b48Spatrick 
344609467b48Spatrick     // In MS inline asm curly braces mark the beginning/end of a block,
344709467b48Spatrick     // therefore they should be interepreted as end of statement
344809467b48Spatrick     CurlyAsEndOfStatement =
3449097a140dSpatrick         isParsingIntelSyntax() && isParsingMSInlineAsm() &&
345009467b48Spatrick         (getLexer().is(AsmToken::LCurly) || getLexer().is(AsmToken::RCurly));
345109467b48Spatrick     if (getLexer().isNot(AsmToken::EndOfStatement) && !CurlyAsEndOfStatement)
345209467b48Spatrick       return TokError("unexpected token in argument list");
345309467b48Spatrick   }
345409467b48Spatrick 
345509467b48Spatrick   // Push the immediate if we extracted one from the mnemonic.
345609467b48Spatrick   if (ComparisonPredicate != ~0U && isParsingIntelSyntax()) {
345709467b48Spatrick     const MCExpr *ImmOp = MCConstantExpr::create(ComparisonPredicate,
345809467b48Spatrick                                                  getParser().getContext());
345909467b48Spatrick     Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
346009467b48Spatrick   }
346109467b48Spatrick 
346209467b48Spatrick   // Consume the EndOfStatement or the prefix separator Slash
346309467b48Spatrick   if (getLexer().is(AsmToken::EndOfStatement) ||
346473471bf0Spatrick       (IsPrefix && getLexer().is(AsmToken::Slash)))
346509467b48Spatrick     Parser.Lex();
346609467b48Spatrick   else if (CurlyAsEndOfStatement)
346709467b48Spatrick     // Add an actual EndOfStatement before the curly brace
346809467b48Spatrick     Info.AsmRewrites->emplace_back(AOK_EndOfStatement,
346909467b48Spatrick                                    getLexer().getTok().getLoc(), 0);
347009467b48Spatrick 
347109467b48Spatrick   // This is for gas compatibility and cannot be done in td.
347209467b48Spatrick   // Adding "p" for some floating point with no argument.
347309467b48Spatrick   // For example: fsub --> fsubp
347409467b48Spatrick   bool IsFp =
347509467b48Spatrick     Name == "fsub" || Name == "fdiv" || Name == "fsubr" || Name == "fdivr";
347609467b48Spatrick   if (IsFp && Operands.size() == 1) {
347709467b48Spatrick     const char *Repl = StringSwitch<const char *>(Name)
347809467b48Spatrick       .Case("fsub", "fsubp")
347909467b48Spatrick       .Case("fdiv", "fdivp")
348009467b48Spatrick       .Case("fsubr", "fsubrp")
348109467b48Spatrick       .Case("fdivr", "fdivrp");
348209467b48Spatrick     static_cast<X86Operand &>(*Operands[0]).setTokenValue(Repl);
348309467b48Spatrick   }
348409467b48Spatrick 
348509467b48Spatrick   if ((Name == "mov" || Name == "movw" || Name == "movl") &&
348609467b48Spatrick       (Operands.size() == 3)) {
348709467b48Spatrick     X86Operand &Op1 = (X86Operand &)*Operands[1];
348809467b48Spatrick     X86Operand &Op2 = (X86Operand &)*Operands[2];
348909467b48Spatrick     SMLoc Loc = Op1.getEndLoc();
349009467b48Spatrick     // Moving a 32 or 16 bit value into a segment register has the same
349109467b48Spatrick     // behavior. Modify such instructions to always take shorter form.
349209467b48Spatrick     if (Op1.isReg() && Op2.isReg() &&
349309467b48Spatrick         X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
349409467b48Spatrick             Op2.getReg()) &&
349509467b48Spatrick         (X86MCRegisterClasses[X86::GR16RegClassID].contains(Op1.getReg()) ||
349609467b48Spatrick          X86MCRegisterClasses[X86::GR32RegClassID].contains(Op1.getReg()))) {
349709467b48Spatrick       // Change instruction name to match new instruction.
349809467b48Spatrick       if (Name != "mov" && Name[3] == (is16BitMode() ? 'l' : 'w')) {
349909467b48Spatrick         Name = is16BitMode() ? "movw" : "movl";
350009467b48Spatrick         Operands[0] = X86Operand::CreateToken(Name, NameLoc);
350109467b48Spatrick       }
350209467b48Spatrick       // Select the correct equivalent 16-/32-bit source register.
350309467b48Spatrick       unsigned Reg =
350409467b48Spatrick           getX86SubSuperRegisterOrZero(Op1.getReg(), is16BitMode() ? 16 : 32);
350509467b48Spatrick       Operands[1] = X86Operand::CreateReg(Reg, Loc, Loc);
350609467b48Spatrick     }
350709467b48Spatrick   }
350809467b48Spatrick 
350909467b48Spatrick   // This is a terrible hack to handle "out[s]?[bwl]? %al, (%dx)" ->
351009467b48Spatrick   // "outb %al, %dx".  Out doesn't take a memory form, but this is a widely
351109467b48Spatrick   // documented form in various unofficial manuals, so a lot of code uses it.
351209467b48Spatrick   if ((Name == "outb" || Name == "outsb" || Name == "outw" || Name == "outsw" ||
351309467b48Spatrick        Name == "outl" || Name == "outsl" || Name == "out" || Name == "outs") &&
351409467b48Spatrick       Operands.size() == 3) {
351509467b48Spatrick     X86Operand &Op = (X86Operand &)*Operands.back();
351609467b48Spatrick     if (Op.isDXReg())
351709467b48Spatrick       Operands.back() = X86Operand::CreateReg(X86::DX, Op.getStartLoc(),
351809467b48Spatrick                                               Op.getEndLoc());
351909467b48Spatrick   }
352009467b48Spatrick   // Same hack for "in[s]?[bwl]? (%dx), %al" -> "inb %dx, %al".
352109467b48Spatrick   if ((Name == "inb" || Name == "insb" || Name == "inw" || Name == "insw" ||
352209467b48Spatrick        Name == "inl" || Name == "insl" || Name == "in" || Name == "ins") &&
352309467b48Spatrick       Operands.size() == 3) {
352409467b48Spatrick     X86Operand &Op = (X86Operand &)*Operands[1];
352509467b48Spatrick     if (Op.isDXReg())
352609467b48Spatrick       Operands[1] = X86Operand::CreateReg(X86::DX, Op.getStartLoc(),
352709467b48Spatrick                                           Op.getEndLoc());
352809467b48Spatrick   }
352909467b48Spatrick 
353009467b48Spatrick   SmallVector<std::unique_ptr<MCParsedAsmOperand>, 2> TmpOperands;
353109467b48Spatrick   bool HadVerifyError = false;
353209467b48Spatrick 
353309467b48Spatrick   // Append default arguments to "ins[bwld]"
353409467b48Spatrick   if (Name.startswith("ins") &&
353509467b48Spatrick       (Operands.size() == 1 || Operands.size() == 3) &&
353609467b48Spatrick       (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd" ||
353709467b48Spatrick        Name == "ins")) {
353809467b48Spatrick 
353909467b48Spatrick     AddDefaultSrcDestOperands(TmpOperands,
354009467b48Spatrick                               X86Operand::CreateReg(X86::DX, NameLoc, NameLoc),
354109467b48Spatrick                               DefaultMemDIOperand(NameLoc));
354209467b48Spatrick     HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
354309467b48Spatrick   }
354409467b48Spatrick 
354509467b48Spatrick   // Append default arguments to "outs[bwld]"
354609467b48Spatrick   if (Name.startswith("outs") &&
354709467b48Spatrick       (Operands.size() == 1 || Operands.size() == 3) &&
354809467b48Spatrick       (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
354909467b48Spatrick        Name == "outsd" || Name == "outs")) {
355009467b48Spatrick     AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
355109467b48Spatrick                               X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
355209467b48Spatrick     HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
355309467b48Spatrick   }
355409467b48Spatrick 
355509467b48Spatrick   // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate
355609467b48Spatrick   // values of $SIREG according to the mode. It would be nice if this
355709467b48Spatrick   // could be achieved with InstAlias in the tables.
355809467b48Spatrick   if (Name.startswith("lods") &&
355909467b48Spatrick       (Operands.size() == 1 || Operands.size() == 2) &&
356009467b48Spatrick       (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
356109467b48Spatrick        Name == "lodsl" || Name == "lodsd" || Name == "lodsq")) {
356209467b48Spatrick     TmpOperands.push_back(DefaultMemSIOperand(NameLoc));
356309467b48Spatrick     HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
356409467b48Spatrick   }
356509467b48Spatrick 
356609467b48Spatrick   // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate
356709467b48Spatrick   // values of $DIREG according to the mode. It would be nice if this
356809467b48Spatrick   // could be achieved with InstAlias in the tables.
356909467b48Spatrick   if (Name.startswith("stos") &&
357009467b48Spatrick       (Operands.size() == 1 || Operands.size() == 2) &&
357109467b48Spatrick       (Name == "stos" || Name == "stosb" || Name == "stosw" ||
357209467b48Spatrick        Name == "stosl" || Name == "stosd" || Name == "stosq")) {
357309467b48Spatrick     TmpOperands.push_back(DefaultMemDIOperand(NameLoc));
357409467b48Spatrick     HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
357509467b48Spatrick   }
357609467b48Spatrick 
357709467b48Spatrick   // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate
357809467b48Spatrick   // values of $DIREG according to the mode. It would be nice if this
357909467b48Spatrick   // could be achieved with InstAlias in the tables.
358009467b48Spatrick   if (Name.startswith("scas") &&
358109467b48Spatrick       (Operands.size() == 1 || Operands.size() == 2) &&
358209467b48Spatrick       (Name == "scas" || Name == "scasb" || Name == "scasw" ||
358309467b48Spatrick        Name == "scasl" || Name == "scasd" || Name == "scasq")) {
358409467b48Spatrick     TmpOperands.push_back(DefaultMemDIOperand(NameLoc));
358509467b48Spatrick     HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
358609467b48Spatrick   }
358709467b48Spatrick 
358809467b48Spatrick   // Add default SI and DI operands to "cmps[bwlq]".
358909467b48Spatrick   if (Name.startswith("cmps") &&
359009467b48Spatrick       (Operands.size() == 1 || Operands.size() == 3) &&
359109467b48Spatrick       (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
359209467b48Spatrick        Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
359309467b48Spatrick     AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
359409467b48Spatrick                               DefaultMemSIOperand(NameLoc));
359509467b48Spatrick     HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
359609467b48Spatrick   }
359709467b48Spatrick 
359809467b48Spatrick   // Add default SI and DI operands to "movs[bwlq]".
359909467b48Spatrick   if (((Name.startswith("movs") &&
360009467b48Spatrick         (Name == "movs" || Name == "movsb" || Name == "movsw" ||
360109467b48Spatrick          Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
360209467b48Spatrick        (Name.startswith("smov") &&
360309467b48Spatrick         (Name == "smov" || Name == "smovb" || Name == "smovw" ||
360409467b48Spatrick          Name == "smovl" || Name == "smovd" || Name == "smovq"))) &&
360509467b48Spatrick       (Operands.size() == 1 || Operands.size() == 3)) {
360609467b48Spatrick     if (Name == "movsd" && Operands.size() == 1 && !isParsingIntelSyntax())
360709467b48Spatrick       Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
360809467b48Spatrick     AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
360909467b48Spatrick                               DefaultMemDIOperand(NameLoc));
361009467b48Spatrick     HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
361109467b48Spatrick   }
361209467b48Spatrick 
361309467b48Spatrick   // Check if we encountered an error for one the string insturctions
361409467b48Spatrick   if (HadVerifyError) {
361509467b48Spatrick     return HadVerifyError;
361609467b48Spatrick   }
361709467b48Spatrick 
361809467b48Spatrick   // Transforms "xlat mem8" into "xlatb"
361909467b48Spatrick   if ((Name == "xlat" || Name == "xlatb") && Operands.size() == 2) {
362009467b48Spatrick     X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
362109467b48Spatrick     if (Op1.isMem8()) {
362209467b48Spatrick       Warning(Op1.getStartLoc(), "memory operand is only for determining the "
362309467b48Spatrick                                  "size, (R|E)BX will be used for the location");
362409467b48Spatrick       Operands.pop_back();
362509467b48Spatrick       static_cast<X86Operand &>(*Operands[0]).setTokenValue("xlatb");
362609467b48Spatrick     }
362709467b48Spatrick   }
362809467b48Spatrick 
362909467b48Spatrick   if (Flags)
363009467b48Spatrick     Operands.push_back(X86Operand::CreatePrefix(Flags, NameLoc, NameLoc));
363109467b48Spatrick   return false;
363209467b48Spatrick }
363309467b48Spatrick 
processInstruction(MCInst & Inst,const OperandVector & Ops)363409467b48Spatrick bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
363509467b48Spatrick   const MCRegisterInfo *MRI = getContext().getRegisterInfo();
363609467b48Spatrick 
363709467b48Spatrick   switch (Inst.getOpcode()) {
363809467b48Spatrick   default: return false;
363973471bf0Spatrick   case X86::JMP_1:
364073471bf0Spatrick     // {disp32} forces a larger displacement as if the instruction was relaxed.
364173471bf0Spatrick     // NOTE: 16-bit mode uses 16-bit displacement even though it says {disp32}.
364273471bf0Spatrick     // This matches GNU assembler.
364373471bf0Spatrick     if (ForcedDispEncoding == DispEncoding_Disp32) {
364473471bf0Spatrick       Inst.setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);
364573471bf0Spatrick       return true;
364673471bf0Spatrick     }
364773471bf0Spatrick 
364873471bf0Spatrick     return false;
364973471bf0Spatrick   case X86::JCC_1:
365073471bf0Spatrick     // {disp32} forces a larger displacement as if the instruction was relaxed.
365173471bf0Spatrick     // NOTE: 16-bit mode uses 16-bit displacement even though it says {disp32}.
365273471bf0Spatrick     // This matches GNU assembler.
365373471bf0Spatrick     if (ForcedDispEncoding == DispEncoding_Disp32) {
365473471bf0Spatrick       Inst.setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);
365573471bf0Spatrick       return true;
365673471bf0Spatrick     }
365773471bf0Spatrick 
365873471bf0Spatrick     return false;
365909467b48Spatrick   case X86::VMOVZPQILo2PQIrr:
366009467b48Spatrick   case X86::VMOVAPDrr:
366109467b48Spatrick   case X86::VMOVAPDYrr:
366209467b48Spatrick   case X86::VMOVAPSrr:
366309467b48Spatrick   case X86::VMOVAPSYrr:
366409467b48Spatrick   case X86::VMOVDQArr:
366509467b48Spatrick   case X86::VMOVDQAYrr:
366609467b48Spatrick   case X86::VMOVDQUrr:
366709467b48Spatrick   case X86::VMOVDQUYrr:
366809467b48Spatrick   case X86::VMOVUPDrr:
366909467b48Spatrick   case X86::VMOVUPDYrr:
367009467b48Spatrick   case X86::VMOVUPSrr:
367109467b48Spatrick   case X86::VMOVUPSYrr: {
367209467b48Spatrick     // We can get a smaller encoding by using VEX.R instead of VEX.B if one of
367309467b48Spatrick     // the registers is extended, but other isn't.
367409467b48Spatrick     if (ForcedVEXEncoding == VEXEncoding_VEX3 ||
367509467b48Spatrick         MRI->getEncodingValue(Inst.getOperand(0).getReg()) >= 8 ||
367609467b48Spatrick         MRI->getEncodingValue(Inst.getOperand(1).getReg()) < 8)
367709467b48Spatrick       return false;
367809467b48Spatrick 
367909467b48Spatrick     unsigned NewOpc;
368009467b48Spatrick     switch (Inst.getOpcode()) {
368109467b48Spatrick     default: llvm_unreachable("Invalid opcode");
368209467b48Spatrick     case X86::VMOVZPQILo2PQIrr: NewOpc = X86::VMOVPQI2QIrr;   break;
368309467b48Spatrick     case X86::VMOVAPDrr:        NewOpc = X86::VMOVAPDrr_REV;  break;
368409467b48Spatrick     case X86::VMOVAPDYrr:       NewOpc = X86::VMOVAPDYrr_REV; break;
368509467b48Spatrick     case X86::VMOVAPSrr:        NewOpc = X86::VMOVAPSrr_REV;  break;
368609467b48Spatrick     case X86::VMOVAPSYrr:       NewOpc = X86::VMOVAPSYrr_REV; break;
368709467b48Spatrick     case X86::VMOVDQArr:        NewOpc = X86::VMOVDQArr_REV;  break;
368809467b48Spatrick     case X86::VMOVDQAYrr:       NewOpc = X86::VMOVDQAYrr_REV; break;
368909467b48Spatrick     case X86::VMOVDQUrr:        NewOpc = X86::VMOVDQUrr_REV;  break;
369009467b48Spatrick     case X86::VMOVDQUYrr:       NewOpc = X86::VMOVDQUYrr_REV; break;
369109467b48Spatrick     case X86::VMOVUPDrr:        NewOpc = X86::VMOVUPDrr_REV;  break;
369209467b48Spatrick     case X86::VMOVUPDYrr:       NewOpc = X86::VMOVUPDYrr_REV; break;
369309467b48Spatrick     case X86::VMOVUPSrr:        NewOpc = X86::VMOVUPSrr_REV;  break;
369409467b48Spatrick     case X86::VMOVUPSYrr:       NewOpc = X86::VMOVUPSYrr_REV; break;
369509467b48Spatrick     }
369609467b48Spatrick     Inst.setOpcode(NewOpc);
369709467b48Spatrick     return true;
369809467b48Spatrick   }
369909467b48Spatrick   case X86::VMOVSDrr:
370009467b48Spatrick   case X86::VMOVSSrr: {
370109467b48Spatrick     // We can get a smaller encoding by using VEX.R instead of VEX.B if one of
370209467b48Spatrick     // the registers is extended, but other isn't.
370309467b48Spatrick     if (ForcedVEXEncoding == VEXEncoding_VEX3 ||
370409467b48Spatrick         MRI->getEncodingValue(Inst.getOperand(0).getReg()) >= 8 ||
370509467b48Spatrick         MRI->getEncodingValue(Inst.getOperand(2).getReg()) < 8)
370609467b48Spatrick       return false;
370709467b48Spatrick 
370809467b48Spatrick     unsigned NewOpc;
370909467b48Spatrick     switch (Inst.getOpcode()) {
371009467b48Spatrick     default: llvm_unreachable("Invalid opcode");
371109467b48Spatrick     case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV; break;
371209467b48Spatrick     case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV; break;
371309467b48Spatrick     }
371409467b48Spatrick     Inst.setOpcode(NewOpc);
371509467b48Spatrick     return true;
371609467b48Spatrick   }
371773471bf0Spatrick   case X86::RCR8ri: case X86::RCR16ri: case X86::RCR32ri: case X86::RCR64ri:
371873471bf0Spatrick   case X86::RCL8ri: case X86::RCL16ri: case X86::RCL32ri: case X86::RCL64ri:
371973471bf0Spatrick   case X86::ROR8ri: case X86::ROR16ri: case X86::ROR32ri: case X86::ROR64ri:
372073471bf0Spatrick   case X86::ROL8ri: case X86::ROL16ri: case X86::ROL32ri: case X86::ROL64ri:
372173471bf0Spatrick   case X86::SAR8ri: case X86::SAR16ri: case X86::SAR32ri: case X86::SAR64ri:
372273471bf0Spatrick   case X86::SHR8ri: case X86::SHR16ri: case X86::SHR32ri: case X86::SHR64ri:
372373471bf0Spatrick   case X86::SHL8ri: case X86::SHL16ri: case X86::SHL32ri: case X86::SHL64ri: {
372473471bf0Spatrick     // Optimize s{hr,ar,hl} $1, <op> to "shift <op>". Similar for rotate.
372573471bf0Spatrick     // FIXME: It would be great if we could just do this with an InstAlias.
372673471bf0Spatrick     if (!Inst.getOperand(2).isImm() || Inst.getOperand(2).getImm() != 1)
372773471bf0Spatrick       return false;
372873471bf0Spatrick 
372973471bf0Spatrick     unsigned NewOpc;
373073471bf0Spatrick     switch (Inst.getOpcode()) {
373173471bf0Spatrick     default: llvm_unreachable("Invalid opcode");
373273471bf0Spatrick     case X86::RCR8ri:  NewOpc = X86::RCR8r1;  break;
373373471bf0Spatrick     case X86::RCR16ri: NewOpc = X86::RCR16r1; break;
373473471bf0Spatrick     case X86::RCR32ri: NewOpc = X86::RCR32r1; break;
373573471bf0Spatrick     case X86::RCR64ri: NewOpc = X86::RCR64r1; break;
373673471bf0Spatrick     case X86::RCL8ri:  NewOpc = X86::RCL8r1;  break;
373773471bf0Spatrick     case X86::RCL16ri: NewOpc = X86::RCL16r1; break;
373873471bf0Spatrick     case X86::RCL32ri: NewOpc = X86::RCL32r1; break;
373973471bf0Spatrick     case X86::RCL64ri: NewOpc = X86::RCL64r1; break;
374073471bf0Spatrick     case X86::ROR8ri:  NewOpc = X86::ROR8r1;  break;
374173471bf0Spatrick     case X86::ROR16ri: NewOpc = X86::ROR16r1; break;
374273471bf0Spatrick     case X86::ROR32ri: NewOpc = X86::ROR32r1; break;
374373471bf0Spatrick     case X86::ROR64ri: NewOpc = X86::ROR64r1; break;
374473471bf0Spatrick     case X86::ROL8ri:  NewOpc = X86::ROL8r1;  break;
374573471bf0Spatrick     case X86::ROL16ri: NewOpc = X86::ROL16r1; break;
374673471bf0Spatrick     case X86::ROL32ri: NewOpc = X86::ROL32r1; break;
374773471bf0Spatrick     case X86::ROL64ri: NewOpc = X86::ROL64r1; break;
374873471bf0Spatrick     case X86::SAR8ri:  NewOpc = X86::SAR8r1;  break;
374973471bf0Spatrick     case X86::SAR16ri: NewOpc = X86::SAR16r1; break;
375073471bf0Spatrick     case X86::SAR32ri: NewOpc = X86::SAR32r1; break;
375173471bf0Spatrick     case X86::SAR64ri: NewOpc = X86::SAR64r1; break;
375273471bf0Spatrick     case X86::SHR8ri:  NewOpc = X86::SHR8r1;  break;
375373471bf0Spatrick     case X86::SHR16ri: NewOpc = X86::SHR16r1; break;
375473471bf0Spatrick     case X86::SHR32ri: NewOpc = X86::SHR32r1; break;
375573471bf0Spatrick     case X86::SHR64ri: NewOpc = X86::SHR64r1; break;
375673471bf0Spatrick     case X86::SHL8ri:  NewOpc = X86::SHL8r1;  break;
375773471bf0Spatrick     case X86::SHL16ri: NewOpc = X86::SHL16r1; break;
375873471bf0Spatrick     case X86::SHL32ri: NewOpc = X86::SHL32r1; break;
375973471bf0Spatrick     case X86::SHL64ri: NewOpc = X86::SHL64r1; break;
376073471bf0Spatrick     }
376173471bf0Spatrick 
376273471bf0Spatrick     MCInst TmpInst;
376373471bf0Spatrick     TmpInst.setOpcode(NewOpc);
376473471bf0Spatrick     TmpInst.addOperand(Inst.getOperand(0));
376573471bf0Spatrick     TmpInst.addOperand(Inst.getOperand(1));
376673471bf0Spatrick     Inst = TmpInst;
376773471bf0Spatrick     return true;
376873471bf0Spatrick   }
376973471bf0Spatrick   case X86::RCR8mi: case X86::RCR16mi: case X86::RCR32mi: case X86::RCR64mi:
377073471bf0Spatrick   case X86::RCL8mi: case X86::RCL16mi: case X86::RCL32mi: case X86::RCL64mi:
377173471bf0Spatrick   case X86::ROR8mi: case X86::ROR16mi: case X86::ROR32mi: case X86::ROR64mi:
377273471bf0Spatrick   case X86::ROL8mi: case X86::ROL16mi: case X86::ROL32mi: case X86::ROL64mi:
377373471bf0Spatrick   case X86::SAR8mi: case X86::SAR16mi: case X86::SAR32mi: case X86::SAR64mi:
377473471bf0Spatrick   case X86::SHR8mi: case X86::SHR16mi: case X86::SHR32mi: case X86::SHR64mi:
377573471bf0Spatrick   case X86::SHL8mi: case X86::SHL16mi: case X86::SHL32mi: case X86::SHL64mi: {
377673471bf0Spatrick     // Optimize s{hr,ar,hl} $1, <op> to "shift <op>". Similar for rotate.
377773471bf0Spatrick     // FIXME: It would be great if we could just do this with an InstAlias.
377873471bf0Spatrick     if (!Inst.getOperand(X86::AddrNumOperands).isImm() ||
377973471bf0Spatrick         Inst.getOperand(X86::AddrNumOperands).getImm() != 1)
378073471bf0Spatrick       return false;
378173471bf0Spatrick 
378273471bf0Spatrick     unsigned NewOpc;
378373471bf0Spatrick     switch (Inst.getOpcode()) {
378473471bf0Spatrick     default: llvm_unreachable("Invalid opcode");
378573471bf0Spatrick     case X86::RCR8mi:  NewOpc = X86::RCR8m1;  break;
378673471bf0Spatrick     case X86::RCR16mi: NewOpc = X86::RCR16m1; break;
378773471bf0Spatrick     case X86::RCR32mi: NewOpc = X86::RCR32m1; break;
378873471bf0Spatrick     case X86::RCR64mi: NewOpc = X86::RCR64m1; break;
378973471bf0Spatrick     case X86::RCL8mi:  NewOpc = X86::RCL8m1;  break;
379073471bf0Spatrick     case X86::RCL16mi: NewOpc = X86::RCL16m1; break;
379173471bf0Spatrick     case X86::RCL32mi: NewOpc = X86::RCL32m1; break;
379273471bf0Spatrick     case X86::RCL64mi: NewOpc = X86::RCL64m1; break;
379373471bf0Spatrick     case X86::ROR8mi:  NewOpc = X86::ROR8m1;  break;
379473471bf0Spatrick     case X86::ROR16mi: NewOpc = X86::ROR16m1; break;
379573471bf0Spatrick     case X86::ROR32mi: NewOpc = X86::ROR32m1; break;
379673471bf0Spatrick     case X86::ROR64mi: NewOpc = X86::ROR64m1; break;
379773471bf0Spatrick     case X86::ROL8mi:  NewOpc = X86::ROL8m1;  break;
379873471bf0Spatrick     case X86::ROL16mi: NewOpc = X86::ROL16m1; break;
379973471bf0Spatrick     case X86::ROL32mi: NewOpc = X86::ROL32m1; break;
380073471bf0Spatrick     case X86::ROL64mi: NewOpc = X86::ROL64m1; break;
380173471bf0Spatrick     case X86::SAR8mi:  NewOpc = X86::SAR8m1;  break;
380273471bf0Spatrick     case X86::SAR16mi: NewOpc = X86::SAR16m1; break;
380373471bf0Spatrick     case X86::SAR32mi: NewOpc = X86::SAR32m1; break;
380473471bf0Spatrick     case X86::SAR64mi: NewOpc = X86::SAR64m1; break;
380573471bf0Spatrick     case X86::SHR8mi:  NewOpc = X86::SHR8m1;  break;
380673471bf0Spatrick     case X86::SHR16mi: NewOpc = X86::SHR16m1; break;
380773471bf0Spatrick     case X86::SHR32mi: NewOpc = X86::SHR32m1; break;
380873471bf0Spatrick     case X86::SHR64mi: NewOpc = X86::SHR64m1; break;
380973471bf0Spatrick     case X86::SHL8mi:  NewOpc = X86::SHL8m1;  break;
381073471bf0Spatrick     case X86::SHL16mi: NewOpc = X86::SHL16m1; break;
381173471bf0Spatrick     case X86::SHL32mi: NewOpc = X86::SHL32m1; break;
381273471bf0Spatrick     case X86::SHL64mi: NewOpc = X86::SHL64m1; break;
381373471bf0Spatrick     }
381473471bf0Spatrick 
381573471bf0Spatrick     MCInst TmpInst;
381673471bf0Spatrick     TmpInst.setOpcode(NewOpc);
381773471bf0Spatrick     for (int i = 0; i != X86::AddrNumOperands; ++i)
381873471bf0Spatrick       TmpInst.addOperand(Inst.getOperand(i));
381973471bf0Spatrick     Inst = TmpInst;
382073471bf0Spatrick     return true;
382173471bf0Spatrick   }
382273471bf0Spatrick   case X86::INT: {
382373471bf0Spatrick     // Transforms "int $3" into "int3" as a size optimization.  We can't write an
382473471bf0Spatrick     // instalias with an immediate operand yet.
382573471bf0Spatrick     if (!Inst.getOperand(0).isImm() || Inst.getOperand(0).getImm() != 3)
382673471bf0Spatrick       return false;
382773471bf0Spatrick 
382873471bf0Spatrick     MCInst TmpInst;
382973471bf0Spatrick     TmpInst.setOpcode(X86::INT3);
383073471bf0Spatrick     Inst = TmpInst;
383173471bf0Spatrick     return true;
383273471bf0Spatrick   }
383309467b48Spatrick   }
383409467b48Spatrick }
383509467b48Spatrick 
validateInstruction(MCInst & Inst,const OperandVector & Ops)383609467b48Spatrick bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
3837*d415bd75Srobert   using namespace X86;
383809467b48Spatrick   const MCRegisterInfo *MRI = getContext().getRegisterInfo();
3839*d415bd75Srobert   unsigned Opcode = Inst.getOpcode();
3840*d415bd75Srobert   uint64_t TSFlags = MII.get(Opcode).TSFlags;
3841*d415bd75Srobert   if (isVFCMADDCPH(Opcode) || isVFCMADDCSH(Opcode) || isVFMADDCPH(Opcode) ||
3842*d415bd75Srobert       isVFMADDCSH(Opcode)) {
3843*d415bd75Srobert     unsigned Dest = Inst.getOperand(0).getReg();
3844*d415bd75Srobert     for (unsigned i = 2; i < Inst.getNumOperands(); i++)
3845*d415bd75Srobert       if (Inst.getOperand(i).isReg() && Dest == Inst.getOperand(i).getReg())
3846*d415bd75Srobert         return Warning(Ops[0]->getStartLoc(), "Destination register should be "
3847*d415bd75Srobert                                               "distinct from source registers");
3848*d415bd75Srobert   } else if (isVFCMULCPH(Opcode) || isVFCMULCSH(Opcode) || isVFMULCPH(Opcode) ||
3849*d415bd75Srobert              isVFMULCSH(Opcode)) {
3850*d415bd75Srobert     unsigned Dest = Inst.getOperand(0).getReg();
3851*d415bd75Srobert     // The mask variants have different operand list. Scan from the third
3852*d415bd75Srobert     // operand to avoid emitting incorrect warning.
3853*d415bd75Srobert     //    VFMULCPHZrr   Dest, Src1, Src2
3854*d415bd75Srobert     //    VFMULCPHZrrk  Dest, Dest, Mask, Src1, Src2
3855*d415bd75Srobert     //    VFMULCPHZrrkz Dest, Mask, Src1, Src2
3856*d415bd75Srobert     for (unsigned i = TSFlags & X86II::EVEX_K ? 2 : 1;
3857*d415bd75Srobert          i < Inst.getNumOperands(); i++)
3858*d415bd75Srobert       if (Inst.getOperand(i).isReg() && Dest == Inst.getOperand(i).getReg())
3859*d415bd75Srobert         return Warning(Ops[0]->getStartLoc(), "Destination register should be "
3860*d415bd75Srobert                                               "distinct from source registers");
3861*d415bd75Srobert   } else if (isV4FMADDPS(Opcode) || isV4FMADDSS(Opcode) ||
3862*d415bd75Srobert              isV4FNMADDPS(Opcode) || isV4FNMADDSS(Opcode) ||
3863*d415bd75Srobert              isVP4DPWSSDS(Opcode) || isVP4DPWSSD(Opcode)) {
386409467b48Spatrick     unsigned Src2 = Inst.getOperand(Inst.getNumOperands() -
386509467b48Spatrick                                     X86::AddrNumOperands - 1).getReg();
386609467b48Spatrick     unsigned Src2Enc = MRI->getEncodingValue(Src2);
386709467b48Spatrick     if (Src2Enc % 4 != 0) {
386809467b48Spatrick       StringRef RegName = X86IntelInstPrinter::getRegisterName(Src2);
386909467b48Spatrick       unsigned GroupStart = (Src2Enc / 4) * 4;
387009467b48Spatrick       unsigned GroupEnd = GroupStart + 3;
387109467b48Spatrick       return Warning(Ops[0]->getStartLoc(),
387209467b48Spatrick                      "source register '" + RegName + "' implicitly denotes '" +
387309467b48Spatrick                      RegName.take_front(3) + Twine(GroupStart) + "' to '" +
387409467b48Spatrick                      RegName.take_front(3) + Twine(GroupEnd) +
387509467b48Spatrick                      "' source group");
387609467b48Spatrick     }
3877*d415bd75Srobert   } else if (isVGATHERDPD(Opcode) || isVGATHERDPS(Opcode) ||
3878*d415bd75Srobert              isVGATHERQPD(Opcode) || isVGATHERQPS(Opcode) ||
3879*d415bd75Srobert              isVPGATHERDD(Opcode) || isVPGATHERDQ(Opcode) ||
3880*d415bd75Srobert              isVPGATHERQD(Opcode) || isVPGATHERQQ(Opcode)) {
3881*d415bd75Srobert     bool HasEVEX = (TSFlags & X86II::EncodingMask) == X86II::EVEX;
3882*d415bd75Srobert     if (HasEVEX) {
3883*d415bd75Srobert       unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg());
3884*d415bd75Srobert       unsigned Index = MRI->getEncodingValue(
3885*d415bd75Srobert           Inst.getOperand(4 + X86::AddrIndexReg).getReg());
3886*d415bd75Srobert       if (Dest == Index)
3887*d415bd75Srobert         return Warning(Ops[0]->getStartLoc(), "index and destination registers "
3888*d415bd75Srobert                                               "should be distinct");
3889*d415bd75Srobert     } else {
3890*d415bd75Srobert       unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg());
3891*d415bd75Srobert       unsigned Mask = MRI->getEncodingValue(Inst.getOperand(1).getReg());
3892*d415bd75Srobert       unsigned Index = MRI->getEncodingValue(
3893*d415bd75Srobert           Inst.getOperand(3 + X86::AddrIndexReg).getReg());
3894*d415bd75Srobert       if (Dest == Mask || Dest == Index || Mask == Index)
3895*d415bd75Srobert         return Warning(Ops[0]->getStartLoc(), "mask, index, and destination "
3896*d415bd75Srobert                                               "registers should be distinct");
389709467b48Spatrick     }
389809467b48Spatrick   }
389909467b48Spatrick 
390073471bf0Spatrick   // Check that we aren't mixing AH/BH/CH/DH with REX prefix. We only need to
390173471bf0Spatrick   // check this with the legacy encoding, VEX/EVEX/XOP don't use REX.
3902*d415bd75Srobert   if ((TSFlags & X86II::EncodingMask) == 0) {
390373471bf0Spatrick     MCPhysReg HReg = X86::NoRegister;
3904*d415bd75Srobert     bool UsesRex = TSFlags & X86II::REX_W;
390573471bf0Spatrick     unsigned NumOps = Inst.getNumOperands();
390673471bf0Spatrick     for (unsigned i = 0; i != NumOps; ++i) {
390773471bf0Spatrick       const MCOperand &MO = Inst.getOperand(i);
390873471bf0Spatrick       if (!MO.isReg())
390973471bf0Spatrick         continue;
391073471bf0Spatrick       unsigned Reg = MO.getReg();
391173471bf0Spatrick       if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH)
391273471bf0Spatrick         HReg = Reg;
391373471bf0Spatrick       if (X86II::isX86_64NonExtLowByteReg(Reg) ||
391473471bf0Spatrick           X86II::isX86_64ExtendedReg(Reg))
391573471bf0Spatrick         UsesRex = true;
391673471bf0Spatrick     }
391773471bf0Spatrick 
391873471bf0Spatrick     if (UsesRex && HReg != X86::NoRegister) {
391973471bf0Spatrick       StringRef RegName = X86IntelInstPrinter::getRegisterName(HReg);
392073471bf0Spatrick       return Error(Ops[0]->getStartLoc(),
392173471bf0Spatrick                    "can't encode '" + RegName + "' in an instruction requiring "
392273471bf0Spatrick                    "REX prefix");
392373471bf0Spatrick     }
392473471bf0Spatrick   }
392573471bf0Spatrick 
392609467b48Spatrick   return false;
392709467b48Spatrick }
392809467b48Spatrick 
392909467b48Spatrick static const char *getSubtargetFeatureName(uint64_t Val);
393009467b48Spatrick 
emitWarningForSpecialLVIInstruction(SMLoc Loc)3931097a140dSpatrick void X86AsmParser::emitWarningForSpecialLVIInstruction(SMLoc Loc) {
3932097a140dSpatrick   Warning(Loc, "Instruction may be vulnerable to LVI and "
3933097a140dSpatrick                "requires manual mitigation");
3934097a140dSpatrick   Note(SMLoc(), "See https://software.intel.com/"
3935097a140dSpatrick                 "security-software-guidance/insights/"
3936097a140dSpatrick                 "deep-dive-load-value-injection#specialinstructions"
3937097a140dSpatrick                 " for more information");
3938097a140dSpatrick }
3939097a140dSpatrick 
3940097a140dSpatrick /// RET instructions and also instructions that indirect calls/jumps from memory
3941097a140dSpatrick /// combine a load and a branch within a single instruction. To mitigate these
3942097a140dSpatrick /// instructions against LVI, they must be decomposed into separate load and
3943097a140dSpatrick /// branch instructions, with an LFENCE in between. For more details, see:
3944097a140dSpatrick /// - X86LoadValueInjectionRetHardening.cpp
3945097a140dSpatrick /// - X86LoadValueInjectionIndirectThunks.cpp
3946097a140dSpatrick /// - https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection
3947097a140dSpatrick ///
3948097a140dSpatrick /// Returns `true` if a mitigation was applied or warning was emitted.
applyLVICFIMitigation(MCInst & Inst,MCStreamer & Out)3949097a140dSpatrick void X86AsmParser::applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out) {
3950097a140dSpatrick   // Information on control-flow instructions that require manual mitigation can
3951097a140dSpatrick   // be found here:
3952097a140dSpatrick   // https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection#specialinstructions
3953097a140dSpatrick   switch (Inst.getOpcode()) {
3954*d415bd75Srobert   case X86::RET16:
3955*d415bd75Srobert   case X86::RET32:
3956*d415bd75Srobert   case X86::RET64:
3957*d415bd75Srobert   case X86::RETI16:
3958*d415bd75Srobert   case X86::RETI32:
3959*d415bd75Srobert   case X86::RETI64: {
3960097a140dSpatrick     MCInst ShlInst, FenceInst;
3961097a140dSpatrick     bool Parse32 = is32BitMode() || Code16GCC;
3962097a140dSpatrick     unsigned Basereg =
3963097a140dSpatrick         is64BitMode() ? X86::RSP : (Parse32 ? X86::ESP : X86::SP);
3964097a140dSpatrick     const MCExpr *Disp = MCConstantExpr::create(0, getContext());
3965097a140dSpatrick     auto ShlMemOp = X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
3966097a140dSpatrick                                           /*BaseReg=*/Basereg, /*IndexReg=*/0,
3967097a140dSpatrick                                           /*Scale=*/1, SMLoc{}, SMLoc{}, 0);
3968097a140dSpatrick     ShlInst.setOpcode(X86::SHL64mi);
3969097a140dSpatrick     ShlMemOp->addMemOperands(ShlInst, 5);
3970097a140dSpatrick     ShlInst.addOperand(MCOperand::createImm(0));
3971097a140dSpatrick     FenceInst.setOpcode(X86::LFENCE);
3972097a140dSpatrick     Out.emitInstruction(ShlInst, getSTI());
3973097a140dSpatrick     Out.emitInstruction(FenceInst, getSTI());
3974097a140dSpatrick     return;
3975097a140dSpatrick   }
3976097a140dSpatrick   case X86::JMP16m:
3977097a140dSpatrick   case X86::JMP32m:
3978097a140dSpatrick   case X86::JMP64m:
3979097a140dSpatrick   case X86::CALL16m:
3980097a140dSpatrick   case X86::CALL32m:
3981097a140dSpatrick   case X86::CALL64m:
3982097a140dSpatrick     emitWarningForSpecialLVIInstruction(Inst.getLoc());
3983097a140dSpatrick     return;
3984097a140dSpatrick   }
3985097a140dSpatrick }
3986097a140dSpatrick 
3987097a140dSpatrick /// To mitigate LVI, every instruction that performs a load can be followed by
3988097a140dSpatrick /// an LFENCE instruction to squash any potential mis-speculation. There are
3989097a140dSpatrick /// some instructions that require additional considerations, and may requre
3990097a140dSpatrick /// manual mitigation. For more details, see:
3991097a140dSpatrick /// https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection
3992097a140dSpatrick ///
3993097a140dSpatrick /// Returns `true` if a mitigation was applied or warning was emitted.
applyLVILoadHardeningMitigation(MCInst & Inst,MCStreamer & Out)3994097a140dSpatrick void X86AsmParser::applyLVILoadHardeningMitigation(MCInst &Inst,
399509467b48Spatrick                                                    MCStreamer &Out) {
3996097a140dSpatrick   auto Opcode = Inst.getOpcode();
3997097a140dSpatrick   auto Flags = Inst.getFlags();
3998097a140dSpatrick   if ((Flags & X86::IP_HAS_REPEAT) || (Flags & X86::IP_HAS_REPEAT_NE)) {
3999097a140dSpatrick     // Information on REP string instructions that require manual mitigation can
4000097a140dSpatrick     // be found here:
4001097a140dSpatrick     // https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection#specialinstructions
4002097a140dSpatrick     switch (Opcode) {
4003097a140dSpatrick     case X86::CMPSB:
4004097a140dSpatrick     case X86::CMPSW:
4005097a140dSpatrick     case X86::CMPSL:
4006097a140dSpatrick     case X86::CMPSQ:
4007097a140dSpatrick     case X86::SCASB:
4008097a140dSpatrick     case X86::SCASW:
4009097a140dSpatrick     case X86::SCASL:
4010097a140dSpatrick     case X86::SCASQ:
4011097a140dSpatrick       emitWarningForSpecialLVIInstruction(Inst.getLoc());
4012097a140dSpatrick       return;
4013097a140dSpatrick     }
4014097a140dSpatrick   } else if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) {
4015097a140dSpatrick     // If a REP instruction is found on its own line, it may or may not be
4016097a140dSpatrick     // followed by a vulnerable instruction. Emit a warning just in case.
4017097a140dSpatrick     emitWarningForSpecialLVIInstruction(Inst.getLoc());
4018097a140dSpatrick     return;
4019097a140dSpatrick   }
4020097a140dSpatrick 
4021097a140dSpatrick   const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
4022097a140dSpatrick 
4023097a140dSpatrick   // Can't mitigate after terminators or calls. A control flow change may have
4024097a140dSpatrick   // already occurred.
4025097a140dSpatrick   if (MCID.isTerminator() || MCID.isCall())
4026097a140dSpatrick     return;
4027097a140dSpatrick 
4028097a140dSpatrick   // LFENCE has the mayLoad property, don't double fence.
4029097a140dSpatrick   if (MCID.mayLoad() && Inst.getOpcode() != X86::LFENCE) {
4030097a140dSpatrick     MCInst FenceInst;
4031097a140dSpatrick     FenceInst.setOpcode(X86::LFENCE);
4032097a140dSpatrick     Out.emitInstruction(FenceInst, getSTI());
4033097a140dSpatrick   }
4034097a140dSpatrick }
4035097a140dSpatrick 
emitInstruction(MCInst & Inst,OperandVector & Operands,MCStreamer & Out)4036097a140dSpatrick void X86AsmParser::emitInstruction(MCInst &Inst, OperandVector &Operands,
4037097a140dSpatrick                                    MCStreamer &Out) {
4038097a140dSpatrick   if (LVIInlineAsmHardening &&
4039097a140dSpatrick       getSTI().getFeatureBits()[X86::FeatureLVIControlFlowIntegrity])
4040097a140dSpatrick     applyLVICFIMitigation(Inst, Out);
4041097a140dSpatrick 
4042097a140dSpatrick   Out.emitInstruction(Inst, getSTI());
4043097a140dSpatrick 
4044097a140dSpatrick   if (LVIInlineAsmHardening &&
4045097a140dSpatrick       getSTI().getFeatureBits()[X86::FeatureLVILoadHardening])
4046097a140dSpatrick     applyLVILoadHardeningMitigation(Inst, Out);
404709467b48Spatrick }
404809467b48Spatrick 
MatchAndEmitInstruction(SMLoc IDLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)404909467b48Spatrick bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
405009467b48Spatrick                                            OperandVector &Operands,
405109467b48Spatrick                                            MCStreamer &Out, uint64_t &ErrorInfo,
405209467b48Spatrick                                            bool MatchingInlineAsm) {
405309467b48Spatrick   if (isParsingIntelSyntax())
405409467b48Spatrick     return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
405509467b48Spatrick                                         MatchingInlineAsm);
405609467b48Spatrick   return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
405709467b48Spatrick                                     MatchingInlineAsm);
405809467b48Spatrick }
405909467b48Spatrick 
MatchFPUWaitAlias(SMLoc IDLoc,X86Operand & Op,OperandVector & Operands,MCStreamer & Out,bool MatchingInlineAsm)406009467b48Spatrick void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
406109467b48Spatrick                                      OperandVector &Operands, MCStreamer &Out,
406209467b48Spatrick                                      bool MatchingInlineAsm) {
406309467b48Spatrick   // FIXME: This should be replaced with a real .td file alias mechanism.
406409467b48Spatrick   // Also, MatchInstructionImpl should actually *do* the EmitInstruction
406509467b48Spatrick   // call.
406609467b48Spatrick   const char *Repl = StringSwitch<const char *>(Op.getToken())
406709467b48Spatrick                          .Case("finit", "fninit")
406809467b48Spatrick                          .Case("fsave", "fnsave")
406909467b48Spatrick                          .Case("fstcw", "fnstcw")
407009467b48Spatrick                          .Case("fstcww", "fnstcw")
407109467b48Spatrick                          .Case("fstenv", "fnstenv")
407209467b48Spatrick                          .Case("fstsw", "fnstsw")
407309467b48Spatrick                          .Case("fstsww", "fnstsw")
407409467b48Spatrick                          .Case("fclex", "fnclex")
407509467b48Spatrick                          .Default(nullptr);
407609467b48Spatrick   if (Repl) {
407709467b48Spatrick     MCInst Inst;
407809467b48Spatrick     Inst.setOpcode(X86::WAIT);
407909467b48Spatrick     Inst.setLoc(IDLoc);
408009467b48Spatrick     if (!MatchingInlineAsm)
4081097a140dSpatrick       emitInstruction(Inst, Operands, Out);
408209467b48Spatrick     Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
408309467b48Spatrick   }
408409467b48Spatrick }
408509467b48Spatrick 
ErrorMissingFeature(SMLoc IDLoc,const FeatureBitset & MissingFeatures,bool MatchingInlineAsm)408609467b48Spatrick bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc,
408709467b48Spatrick                                        const FeatureBitset &MissingFeatures,
408809467b48Spatrick                                        bool MatchingInlineAsm) {
408909467b48Spatrick   assert(MissingFeatures.any() && "Unknown missing feature!");
409009467b48Spatrick   SmallString<126> Msg;
409109467b48Spatrick   raw_svector_ostream OS(Msg);
409209467b48Spatrick   OS << "instruction requires:";
409309467b48Spatrick   for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {
409409467b48Spatrick     if (MissingFeatures[i])
409509467b48Spatrick       OS << ' ' << getSubtargetFeatureName(i);
409609467b48Spatrick   }
409709467b48Spatrick   return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
409809467b48Spatrick }
409909467b48Spatrick 
getPrefixes(OperandVector & Operands)410009467b48Spatrick static unsigned getPrefixes(OperandVector &Operands) {
410109467b48Spatrick   unsigned Result = 0;
410209467b48Spatrick   X86Operand &Prefix = static_cast<X86Operand &>(*Operands.back());
410309467b48Spatrick   if (Prefix.isPrefix()) {
410409467b48Spatrick     Result = Prefix.getPrefix();
410509467b48Spatrick     Operands.pop_back();
410609467b48Spatrick   }
410709467b48Spatrick   return Result;
410809467b48Spatrick }
410909467b48Spatrick 
checkTargetMatchPredicate(MCInst & Inst)411009467b48Spatrick unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {
411109467b48Spatrick   unsigned Opc = Inst.getOpcode();
411209467b48Spatrick   const MCInstrDesc &MCID = MII.get(Opc);
411309467b48Spatrick 
411409467b48Spatrick   if (ForcedVEXEncoding == VEXEncoding_EVEX &&
411509467b48Spatrick       (MCID.TSFlags & X86II::EncodingMask) != X86II::EVEX)
411609467b48Spatrick     return Match_Unsupported;
411709467b48Spatrick 
4118097a140dSpatrick   if ((ForcedVEXEncoding == VEXEncoding_VEX ||
411973471bf0Spatrick        ForcedVEXEncoding == VEXEncoding_VEX2 ||
412009467b48Spatrick        ForcedVEXEncoding == VEXEncoding_VEX3) &&
412109467b48Spatrick       (MCID.TSFlags & X86II::EncodingMask) != X86II::VEX)
412209467b48Spatrick     return Match_Unsupported;
412309467b48Spatrick 
412473471bf0Spatrick   // These instructions are only available with {vex}, {vex2} or {vex3} prefix
412573471bf0Spatrick   if (MCID.TSFlags & X86II::ExplicitVEXPrefix &&
412673471bf0Spatrick       (ForcedVEXEncoding != VEXEncoding_VEX &&
412773471bf0Spatrick        ForcedVEXEncoding != VEXEncoding_VEX2 &&
412873471bf0Spatrick        ForcedVEXEncoding != VEXEncoding_VEX3))
412973471bf0Spatrick     return Match_Unsupported;
413073471bf0Spatrick 
413109467b48Spatrick   return Match_Success;
413209467b48Spatrick }
413309467b48Spatrick 
MatchAndEmitATTInstruction(SMLoc IDLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)413409467b48Spatrick bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
413509467b48Spatrick                                               OperandVector &Operands,
413609467b48Spatrick                                               MCStreamer &Out,
413709467b48Spatrick                                               uint64_t &ErrorInfo,
413809467b48Spatrick                                               bool MatchingInlineAsm) {
413909467b48Spatrick   assert(!Operands.empty() && "Unexpect empty operand list!");
414009467b48Spatrick   assert((*Operands[0]).isToken() && "Leading operand should always be a mnemonic!");
4141*d415bd75Srobert   SMRange EmptyRange = std::nullopt;
414209467b48Spatrick 
414309467b48Spatrick   // First, handle aliases that expand to multiple instructions.
414409467b48Spatrick   MatchFPUWaitAlias(IDLoc, static_cast<X86Operand &>(*Operands[0]), Operands,
414509467b48Spatrick                     Out, MatchingInlineAsm);
414609467b48Spatrick   X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
414709467b48Spatrick   unsigned Prefixes = getPrefixes(Operands);
414809467b48Spatrick 
414909467b48Spatrick   MCInst Inst;
415009467b48Spatrick 
415173471bf0Spatrick   // If VEX/EVEX encoding is forced, we need to pass the USE_* flag to the
415273471bf0Spatrick   // encoder and printer.
415373471bf0Spatrick   if (ForcedVEXEncoding == VEXEncoding_VEX)
415473471bf0Spatrick     Prefixes |= X86::IP_USE_VEX;
415573471bf0Spatrick   else if (ForcedVEXEncoding == VEXEncoding_VEX2)
415673471bf0Spatrick     Prefixes |= X86::IP_USE_VEX2;
415773471bf0Spatrick   else if (ForcedVEXEncoding == VEXEncoding_VEX3)
415809467b48Spatrick     Prefixes |= X86::IP_USE_VEX3;
415973471bf0Spatrick   else if (ForcedVEXEncoding == VEXEncoding_EVEX)
416073471bf0Spatrick     Prefixes |= X86::IP_USE_EVEX;
416173471bf0Spatrick 
416273471bf0Spatrick   // Set encoded flags for {disp8} and {disp32}.
416373471bf0Spatrick   if (ForcedDispEncoding == DispEncoding_Disp8)
416473471bf0Spatrick     Prefixes |= X86::IP_USE_DISP8;
416573471bf0Spatrick   else if (ForcedDispEncoding == DispEncoding_Disp32)
416673471bf0Spatrick     Prefixes |= X86::IP_USE_DISP32;
416709467b48Spatrick 
416809467b48Spatrick   if (Prefixes)
416909467b48Spatrick     Inst.setFlags(Prefixes);
417009467b48Spatrick 
417173471bf0Spatrick   // In 16-bit mode, if data32 is specified, temporarily switch to 32-bit mode
417273471bf0Spatrick   // when matching the instruction.
4173*d415bd75Srobert   if (ForcedDataPrefix == X86::Is32Bit)
4174*d415bd75Srobert     SwitchMode(X86::Is32Bit);
417509467b48Spatrick   // First, try a direct match.
417609467b48Spatrick   FeatureBitset MissingFeatures;
417709467b48Spatrick   unsigned OriginalError = MatchInstruction(Operands, Inst, ErrorInfo,
417809467b48Spatrick                                             MissingFeatures, MatchingInlineAsm,
417909467b48Spatrick                                             isParsingIntelSyntax());
4180*d415bd75Srobert   if (ForcedDataPrefix == X86::Is32Bit) {
4181*d415bd75Srobert     SwitchMode(X86::Is16Bit);
418273471bf0Spatrick     ForcedDataPrefix = 0;
418373471bf0Spatrick   }
418409467b48Spatrick   switch (OriginalError) {
418509467b48Spatrick   default: llvm_unreachable("Unexpected match result!");
418609467b48Spatrick   case Match_Success:
418709467b48Spatrick     if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
418809467b48Spatrick       return true;
418909467b48Spatrick     // Some instructions need post-processing to, for example, tweak which
419009467b48Spatrick     // encoding is selected. Loop on it while changes happen so the
419109467b48Spatrick     // individual transformations can chain off each other.
419209467b48Spatrick     if (!MatchingInlineAsm)
419309467b48Spatrick       while (processInstruction(Inst, Operands))
419409467b48Spatrick         ;
419509467b48Spatrick 
419609467b48Spatrick     Inst.setLoc(IDLoc);
419709467b48Spatrick     if (!MatchingInlineAsm)
4198097a140dSpatrick       emitInstruction(Inst, Operands, Out);
419909467b48Spatrick     Opcode = Inst.getOpcode();
420009467b48Spatrick     return false;
420109467b48Spatrick   case Match_InvalidImmUnsignedi4: {
420209467b48Spatrick     SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
420309467b48Spatrick     if (ErrorLoc == SMLoc())
420409467b48Spatrick       ErrorLoc = IDLoc;
420509467b48Spatrick     return Error(ErrorLoc, "immediate must be an integer in range [0, 15]",
420609467b48Spatrick                  EmptyRange, MatchingInlineAsm);
420709467b48Spatrick   }
420809467b48Spatrick   case Match_MissingFeature:
420909467b48Spatrick     return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);
421009467b48Spatrick   case Match_InvalidOperand:
421109467b48Spatrick   case Match_MnemonicFail:
421209467b48Spatrick   case Match_Unsupported:
421309467b48Spatrick     break;
421409467b48Spatrick   }
421509467b48Spatrick   if (Op.getToken().empty()) {
421609467b48Spatrick     Error(IDLoc, "instruction must have size higher than 0", EmptyRange,
421709467b48Spatrick           MatchingInlineAsm);
421809467b48Spatrick     return true;
421909467b48Spatrick   }
422009467b48Spatrick 
422109467b48Spatrick   // FIXME: Ideally, we would only attempt suffix matches for things which are
422209467b48Spatrick   // valid prefixes, and we could just infer the right unambiguous
422309467b48Spatrick   // type. However, that requires substantially more matcher support than the
422409467b48Spatrick   // following hack.
422509467b48Spatrick 
422609467b48Spatrick   // Change the operand to point to a temporary token.
422709467b48Spatrick   StringRef Base = Op.getToken();
422809467b48Spatrick   SmallString<16> Tmp;
422909467b48Spatrick   Tmp += Base;
423009467b48Spatrick   Tmp += ' ';
423109467b48Spatrick   Op.setTokenValue(Tmp);
423209467b48Spatrick 
423309467b48Spatrick   // If this instruction starts with an 'f', then it is a floating point stack
423409467b48Spatrick   // instruction.  These come in up to three forms for 32-bit, 64-bit, and
423509467b48Spatrick   // 80-bit floating point, which use the suffixes s,l,t respectively.
423609467b48Spatrick   //
423709467b48Spatrick   // Otherwise, we assume that this may be an integer instruction, which comes
423809467b48Spatrick   // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
423909467b48Spatrick   const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
4240097a140dSpatrick   // MemSize corresponding to Suffixes.  { 8, 16, 32, 64 }    { 32, 64, 80, 0 }
4241097a140dSpatrick   const char *MemSize = Base[0] != 'f' ? "\x08\x10\x20\x40" : "\x20\x40\x50\0";
424209467b48Spatrick 
424309467b48Spatrick   // Check for the various suffix matches.
424409467b48Spatrick   uint64_t ErrorInfoIgnore;
424509467b48Spatrick   FeatureBitset ErrorInfoMissingFeatures; // Init suppresses compiler warnings.
424609467b48Spatrick   unsigned Match[4];
424709467b48Spatrick 
4248097a140dSpatrick   // Some instruction like VPMULDQ is NOT the variant of VPMULD but a new one.
4249097a140dSpatrick   // So we should make sure the suffix matcher only works for memory variant
4250097a140dSpatrick   // that has the same size with the suffix.
4251097a140dSpatrick   // FIXME: This flag is a workaround for legacy instructions that didn't
4252097a140dSpatrick   // declare non suffix variant assembly.
4253097a140dSpatrick   bool HasVectorReg = false;
4254097a140dSpatrick   X86Operand *MemOp = nullptr;
4255097a140dSpatrick   for (const auto &Op : Operands) {
4256097a140dSpatrick     X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
4257097a140dSpatrick     if (X86Op->isVectorReg())
4258097a140dSpatrick       HasVectorReg = true;
4259097a140dSpatrick     else if (X86Op->isMem()) {
4260097a140dSpatrick       MemOp = X86Op;
4261097a140dSpatrick       assert(MemOp->Mem.Size == 0 && "Memory size always 0 under ATT syntax");
4262097a140dSpatrick       // Have we found an unqualified memory operand,
4263097a140dSpatrick       // break. IA allows only one memory operand.
4264097a140dSpatrick       break;
4265097a140dSpatrick     }
4266097a140dSpatrick   }
4267097a140dSpatrick 
4268*d415bd75Srobert   for (unsigned I = 0, E = std::size(Match); I != E; ++I) {
426909467b48Spatrick     Tmp.back() = Suffixes[I];
4270097a140dSpatrick     if (MemOp && HasVectorReg)
4271097a140dSpatrick       MemOp->Mem.Size = MemSize[I];
4272097a140dSpatrick     Match[I] = Match_MnemonicFail;
4273097a140dSpatrick     if (MemOp || !HasVectorReg) {
4274097a140dSpatrick       Match[I] =
4275097a140dSpatrick           MatchInstruction(Operands, Inst, ErrorInfoIgnore, MissingFeatures,
4276097a140dSpatrick                            MatchingInlineAsm, isParsingIntelSyntax());
427709467b48Spatrick       // If this returned as a missing feature failure, remember that.
427809467b48Spatrick       if (Match[I] == Match_MissingFeature)
427909467b48Spatrick         ErrorInfoMissingFeatures = MissingFeatures;
428009467b48Spatrick     }
4281097a140dSpatrick   }
428209467b48Spatrick 
428309467b48Spatrick   // Restore the old token.
428409467b48Spatrick   Op.setTokenValue(Base);
428509467b48Spatrick 
428609467b48Spatrick   // If exactly one matched, then we treat that as a successful match (and the
428709467b48Spatrick   // instruction will already have been filled in correctly, since the failing
428809467b48Spatrick   // matches won't have modified it).
4289*d415bd75Srobert   unsigned NumSuccessfulMatches = llvm::count(Match, Match_Success);
429009467b48Spatrick   if (NumSuccessfulMatches == 1) {
429173471bf0Spatrick     if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
429273471bf0Spatrick       return true;
429373471bf0Spatrick     // Some instructions need post-processing to, for example, tweak which
429473471bf0Spatrick     // encoding is selected. Loop on it while changes happen so the
429573471bf0Spatrick     // individual transformations can chain off each other.
429673471bf0Spatrick     if (!MatchingInlineAsm)
429773471bf0Spatrick       while (processInstruction(Inst, Operands))
429873471bf0Spatrick         ;
429973471bf0Spatrick 
430009467b48Spatrick     Inst.setLoc(IDLoc);
430109467b48Spatrick     if (!MatchingInlineAsm)
4302097a140dSpatrick       emitInstruction(Inst, Operands, Out);
430309467b48Spatrick     Opcode = Inst.getOpcode();
430409467b48Spatrick     return false;
430509467b48Spatrick   }
430609467b48Spatrick 
430709467b48Spatrick   // Otherwise, the match failed, try to produce a decent error message.
430809467b48Spatrick 
430909467b48Spatrick   // If we had multiple suffix matches, then identify this as an ambiguous
431009467b48Spatrick   // match.
431109467b48Spatrick   if (NumSuccessfulMatches > 1) {
431209467b48Spatrick     char MatchChars[4];
431309467b48Spatrick     unsigned NumMatches = 0;
4314*d415bd75Srobert     for (unsigned I = 0, E = std::size(Match); I != E; ++I)
431509467b48Spatrick       if (Match[I] == Match_Success)
431609467b48Spatrick         MatchChars[NumMatches++] = Suffixes[I];
431709467b48Spatrick 
431809467b48Spatrick     SmallString<126> Msg;
431909467b48Spatrick     raw_svector_ostream OS(Msg);
432009467b48Spatrick     OS << "ambiguous instructions require an explicit suffix (could be ";
432109467b48Spatrick     for (unsigned i = 0; i != NumMatches; ++i) {
432209467b48Spatrick       if (i != 0)
432309467b48Spatrick         OS << ", ";
432409467b48Spatrick       if (i + 1 == NumMatches)
432509467b48Spatrick         OS << "or ";
432609467b48Spatrick       OS << "'" << Base << MatchChars[i] << "'";
432709467b48Spatrick     }
432809467b48Spatrick     OS << ")";
432909467b48Spatrick     Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
433009467b48Spatrick     return true;
433109467b48Spatrick   }
433209467b48Spatrick 
433309467b48Spatrick   // Okay, we know that none of the variants matched successfully.
433409467b48Spatrick 
433509467b48Spatrick   // If all of the instructions reported an invalid mnemonic, then the original
433609467b48Spatrick   // mnemonic was invalid.
4337*d415bd75Srobert   if (llvm::count(Match, Match_MnemonicFail) == 4) {
433809467b48Spatrick     if (OriginalError == Match_MnemonicFail)
433909467b48Spatrick       return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
434009467b48Spatrick                    Op.getLocRange(), MatchingInlineAsm);
434109467b48Spatrick 
434209467b48Spatrick     if (OriginalError == Match_Unsupported)
434309467b48Spatrick       return Error(IDLoc, "unsupported instruction", EmptyRange,
434409467b48Spatrick                    MatchingInlineAsm);
434509467b48Spatrick 
434609467b48Spatrick     assert(OriginalError == Match_InvalidOperand && "Unexpected error");
434709467b48Spatrick     // Recover location info for the operand if we know which was the problem.
434809467b48Spatrick     if (ErrorInfo != ~0ULL) {
434909467b48Spatrick       if (ErrorInfo >= Operands.size())
435009467b48Spatrick         return Error(IDLoc, "too few operands for instruction", EmptyRange,
435109467b48Spatrick                      MatchingInlineAsm);
435209467b48Spatrick 
435309467b48Spatrick       X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
435409467b48Spatrick       if (Operand.getStartLoc().isValid()) {
435509467b48Spatrick         SMRange OperandRange = Operand.getLocRange();
435609467b48Spatrick         return Error(Operand.getStartLoc(), "invalid operand for instruction",
435709467b48Spatrick                      OperandRange, MatchingInlineAsm);
435809467b48Spatrick       }
435909467b48Spatrick     }
436009467b48Spatrick 
436109467b48Spatrick     return Error(IDLoc, "invalid operand for instruction", EmptyRange,
436209467b48Spatrick                  MatchingInlineAsm);
436309467b48Spatrick   }
436409467b48Spatrick 
436509467b48Spatrick   // If one instruction matched as unsupported, report this as unsupported.
4366*d415bd75Srobert   if (llvm::count(Match, Match_Unsupported) == 1) {
436709467b48Spatrick     return Error(IDLoc, "unsupported instruction", EmptyRange,
436809467b48Spatrick                  MatchingInlineAsm);
436909467b48Spatrick   }
437009467b48Spatrick 
437109467b48Spatrick   // If one instruction matched with a missing feature, report this as a
437209467b48Spatrick   // missing feature.
4373*d415bd75Srobert   if (llvm::count(Match, Match_MissingFeature) == 1) {
437409467b48Spatrick     ErrorInfo = Match_MissingFeature;
437509467b48Spatrick     return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
437609467b48Spatrick                                MatchingInlineAsm);
437709467b48Spatrick   }
437809467b48Spatrick 
437909467b48Spatrick   // If one instruction matched with an invalid operand, report this as an
438009467b48Spatrick   // operand failure.
4381*d415bd75Srobert   if (llvm::count(Match, Match_InvalidOperand) == 1) {
438209467b48Spatrick     return Error(IDLoc, "invalid operand for instruction", EmptyRange,
438309467b48Spatrick                  MatchingInlineAsm);
438409467b48Spatrick   }
438509467b48Spatrick 
438609467b48Spatrick   // If all of these were an outright failure, report it in a useless way.
438709467b48Spatrick   Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
438809467b48Spatrick         EmptyRange, MatchingInlineAsm);
438909467b48Spatrick   return true;
439009467b48Spatrick }
439109467b48Spatrick 
MatchAndEmitIntelInstruction(SMLoc IDLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)439209467b48Spatrick bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
439309467b48Spatrick                                                 OperandVector &Operands,
439409467b48Spatrick                                                 MCStreamer &Out,
439509467b48Spatrick                                                 uint64_t &ErrorInfo,
439609467b48Spatrick                                                 bool MatchingInlineAsm) {
439709467b48Spatrick   assert(!Operands.empty() && "Unexpect empty operand list!");
439809467b48Spatrick   assert((*Operands[0]).isToken() && "Leading operand should always be a mnemonic!");
439909467b48Spatrick   StringRef Mnemonic = (static_cast<X86Operand &>(*Operands[0])).getToken();
4400*d415bd75Srobert   SMRange EmptyRange = std::nullopt;
440109467b48Spatrick   StringRef Base = (static_cast<X86Operand &>(*Operands[0])).getToken();
440209467b48Spatrick   unsigned Prefixes = getPrefixes(Operands);
440309467b48Spatrick 
440409467b48Spatrick   // First, handle aliases that expand to multiple instructions.
440509467b48Spatrick   MatchFPUWaitAlias(IDLoc, static_cast<X86Operand &>(*Operands[0]), Operands, Out, MatchingInlineAsm);
440609467b48Spatrick   X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
440709467b48Spatrick 
440809467b48Spatrick   MCInst Inst;
440909467b48Spatrick 
441073471bf0Spatrick   // If VEX/EVEX encoding is forced, we need to pass the USE_* flag to the
441173471bf0Spatrick   // encoder and printer.
441273471bf0Spatrick   if (ForcedVEXEncoding == VEXEncoding_VEX)
441373471bf0Spatrick     Prefixes |= X86::IP_USE_VEX;
441473471bf0Spatrick   else if (ForcedVEXEncoding == VEXEncoding_VEX2)
441573471bf0Spatrick     Prefixes |= X86::IP_USE_VEX2;
441673471bf0Spatrick   else if (ForcedVEXEncoding == VEXEncoding_VEX3)
441709467b48Spatrick     Prefixes |= X86::IP_USE_VEX3;
441873471bf0Spatrick   else if (ForcedVEXEncoding == VEXEncoding_EVEX)
441973471bf0Spatrick     Prefixes |= X86::IP_USE_EVEX;
442073471bf0Spatrick 
442173471bf0Spatrick   // Set encoded flags for {disp8} and {disp32}.
442273471bf0Spatrick   if (ForcedDispEncoding == DispEncoding_Disp8)
442373471bf0Spatrick     Prefixes |= X86::IP_USE_DISP8;
442473471bf0Spatrick   else if (ForcedDispEncoding == DispEncoding_Disp32)
442573471bf0Spatrick     Prefixes |= X86::IP_USE_DISP32;
442609467b48Spatrick 
442709467b48Spatrick   if (Prefixes)
442809467b48Spatrick     Inst.setFlags(Prefixes);
442909467b48Spatrick 
443009467b48Spatrick   // Find one unsized memory operand, if present.
443109467b48Spatrick   X86Operand *UnsizedMemOp = nullptr;
443209467b48Spatrick   for (const auto &Op : Operands) {
443309467b48Spatrick     X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
443409467b48Spatrick     if (X86Op->isMemUnsized()) {
443509467b48Spatrick       UnsizedMemOp = X86Op;
443609467b48Spatrick       // Have we found an unqualified memory operand,
443709467b48Spatrick       // break. IA allows only one memory operand.
443809467b48Spatrick       break;
443909467b48Spatrick     }
444009467b48Spatrick   }
444109467b48Spatrick 
444209467b48Spatrick   // Allow some instructions to have implicitly pointer-sized operands.  This is
444309467b48Spatrick   // compatible with gas.
444409467b48Spatrick   if (UnsizedMemOp) {
444509467b48Spatrick     static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
444609467b48Spatrick     for (const char *Instr : PtrSizedInstrs) {
444709467b48Spatrick       if (Mnemonic == Instr) {
444809467b48Spatrick         UnsizedMemOp->Mem.Size = getPointerWidth();
444909467b48Spatrick         break;
445009467b48Spatrick       }
445109467b48Spatrick     }
445209467b48Spatrick   }
445309467b48Spatrick 
445409467b48Spatrick   SmallVector<unsigned, 8> Match;
445509467b48Spatrick   FeatureBitset ErrorInfoMissingFeatures;
445609467b48Spatrick   FeatureBitset MissingFeatures;
445709467b48Spatrick 
445809467b48Spatrick   // If unsized push has immediate operand we should default the default pointer
445909467b48Spatrick   // size for the size.
446009467b48Spatrick   if (Mnemonic == "push" && Operands.size() == 2) {
446109467b48Spatrick     auto *X86Op = static_cast<X86Operand *>(Operands[1].get());
446209467b48Spatrick     if (X86Op->isImm()) {
446309467b48Spatrick       // If it's not a constant fall through and let remainder take care of it.
446409467b48Spatrick       const auto *CE = dyn_cast<MCConstantExpr>(X86Op->getImm());
446509467b48Spatrick       unsigned Size = getPointerWidth();
446609467b48Spatrick       if (CE &&
446709467b48Spatrick           (isIntN(Size, CE->getValue()) || isUIntN(Size, CE->getValue()))) {
446809467b48Spatrick         SmallString<16> Tmp;
446909467b48Spatrick         Tmp += Base;
447009467b48Spatrick         Tmp += (is64BitMode())
447109467b48Spatrick                    ? "q"
447209467b48Spatrick                    : (is32BitMode()) ? "l" : (is16BitMode()) ? "w" : " ";
447309467b48Spatrick         Op.setTokenValue(Tmp);
447409467b48Spatrick         // Do match in ATT mode to allow explicit suffix usage.
447509467b48Spatrick         Match.push_back(MatchInstruction(Operands, Inst, ErrorInfo,
447609467b48Spatrick                                          MissingFeatures, MatchingInlineAsm,
447709467b48Spatrick                                          false /*isParsingIntelSyntax()*/));
447809467b48Spatrick         Op.setTokenValue(Base);
447909467b48Spatrick       }
448009467b48Spatrick     }
448109467b48Spatrick   }
448209467b48Spatrick 
448309467b48Spatrick   // If an unsized memory operand is present, try to match with each memory
448409467b48Spatrick   // operand size.  In Intel assembly, the size is not part of the instruction
448509467b48Spatrick   // mnemonic.
448609467b48Spatrick   if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
448709467b48Spatrick     static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
448809467b48Spatrick     for (unsigned Size : MopSizes) {
448909467b48Spatrick       UnsizedMemOp->Mem.Size = Size;
449009467b48Spatrick       uint64_t ErrorInfoIgnore;
449109467b48Spatrick       unsigned LastOpcode = Inst.getOpcode();
449209467b48Spatrick       unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
449309467b48Spatrick                                     MissingFeatures, MatchingInlineAsm,
449409467b48Spatrick                                     isParsingIntelSyntax());
449509467b48Spatrick       if (Match.empty() || LastOpcode != Inst.getOpcode())
449609467b48Spatrick         Match.push_back(M);
449709467b48Spatrick 
449809467b48Spatrick       // If this returned as a missing feature failure, remember that.
449909467b48Spatrick       if (Match.back() == Match_MissingFeature)
450009467b48Spatrick         ErrorInfoMissingFeatures = MissingFeatures;
450109467b48Spatrick     }
450209467b48Spatrick 
450309467b48Spatrick     // Restore the size of the unsized memory operand if we modified it.
450409467b48Spatrick     UnsizedMemOp->Mem.Size = 0;
450509467b48Spatrick   }
450609467b48Spatrick 
450709467b48Spatrick   // If we haven't matched anything yet, this is not a basic integer or FPU
450809467b48Spatrick   // operation.  There shouldn't be any ambiguity in our mnemonic table, so try
450909467b48Spatrick   // matching with the unsized operand.
451009467b48Spatrick   if (Match.empty()) {
451109467b48Spatrick     Match.push_back(MatchInstruction(
451209467b48Spatrick         Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
451309467b48Spatrick         isParsingIntelSyntax()));
451409467b48Spatrick     // If this returned as a missing feature failure, remember that.
451509467b48Spatrick     if (Match.back() == Match_MissingFeature)
451609467b48Spatrick       ErrorInfoMissingFeatures = MissingFeatures;
451709467b48Spatrick   }
451809467b48Spatrick 
451909467b48Spatrick   // Restore the size of the unsized memory operand if we modified it.
452009467b48Spatrick   if (UnsizedMemOp)
452109467b48Spatrick     UnsizedMemOp->Mem.Size = 0;
452209467b48Spatrick 
452309467b48Spatrick   // If it's a bad mnemonic, all results will be the same.
452409467b48Spatrick   if (Match.back() == Match_MnemonicFail) {
452509467b48Spatrick     return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
452609467b48Spatrick                  Op.getLocRange(), MatchingInlineAsm);
452709467b48Spatrick   }
452809467b48Spatrick 
4529*d415bd75Srobert   unsigned NumSuccessfulMatches = llvm::count(Match, Match_Success);
453009467b48Spatrick 
453109467b48Spatrick   // If matching was ambiguous and we had size information from the frontend,
453209467b48Spatrick   // try again with that. This handles cases like "movxz eax, m8/m16".
453309467b48Spatrick   if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
453409467b48Spatrick       UnsizedMemOp->getMemFrontendSize()) {
453509467b48Spatrick     UnsizedMemOp->Mem.Size = UnsizedMemOp->getMemFrontendSize();
453609467b48Spatrick     unsigned M = MatchInstruction(
453709467b48Spatrick         Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
453809467b48Spatrick         isParsingIntelSyntax());
453909467b48Spatrick     if (M == Match_Success)
454009467b48Spatrick       NumSuccessfulMatches = 1;
454109467b48Spatrick 
454209467b48Spatrick     // Add a rewrite that encodes the size information we used from the
454309467b48Spatrick     // frontend.
454409467b48Spatrick     InstInfo->AsmRewrites->emplace_back(
454509467b48Spatrick         AOK_SizeDirective, UnsizedMemOp->getStartLoc(),
454609467b48Spatrick         /*Len=*/0, UnsizedMemOp->getMemFrontendSize());
454709467b48Spatrick   }
454809467b48Spatrick 
454909467b48Spatrick   // If exactly one matched, then we treat that as a successful match (and the
455009467b48Spatrick   // instruction will already have been filled in correctly, since the failing
455109467b48Spatrick   // matches won't have modified it).
455209467b48Spatrick   if (NumSuccessfulMatches == 1) {
455309467b48Spatrick     if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
455409467b48Spatrick       return true;
455509467b48Spatrick     // Some instructions need post-processing to, for example, tweak which
455609467b48Spatrick     // encoding is selected. Loop on it while changes happen so the individual
455709467b48Spatrick     // transformations can chain off each other.
455809467b48Spatrick     if (!MatchingInlineAsm)
455909467b48Spatrick       while (processInstruction(Inst, Operands))
456009467b48Spatrick         ;
456109467b48Spatrick     Inst.setLoc(IDLoc);
456209467b48Spatrick     if (!MatchingInlineAsm)
4563097a140dSpatrick       emitInstruction(Inst, Operands, Out);
456409467b48Spatrick     Opcode = Inst.getOpcode();
456509467b48Spatrick     return false;
456609467b48Spatrick   } else if (NumSuccessfulMatches > 1) {
456709467b48Spatrick     assert(UnsizedMemOp &&
456809467b48Spatrick            "multiple matches only possible with unsized memory operands");
456909467b48Spatrick     return Error(UnsizedMemOp->getStartLoc(),
457009467b48Spatrick                  "ambiguous operand size for instruction '" + Mnemonic + "\'",
457109467b48Spatrick                  UnsizedMemOp->getLocRange());
457209467b48Spatrick   }
457309467b48Spatrick 
457409467b48Spatrick   // If one instruction matched as unsupported, report this as unsupported.
4575*d415bd75Srobert   if (llvm::count(Match, Match_Unsupported) == 1) {
457609467b48Spatrick     return Error(IDLoc, "unsupported instruction", EmptyRange,
457709467b48Spatrick                  MatchingInlineAsm);
457809467b48Spatrick   }
457909467b48Spatrick 
458009467b48Spatrick   // If one instruction matched with a missing feature, report this as a
458109467b48Spatrick   // missing feature.
4582*d415bd75Srobert   if (llvm::count(Match, Match_MissingFeature) == 1) {
458309467b48Spatrick     ErrorInfo = Match_MissingFeature;
458409467b48Spatrick     return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
458509467b48Spatrick                                MatchingInlineAsm);
458609467b48Spatrick   }
458709467b48Spatrick 
458809467b48Spatrick   // If one instruction matched with an invalid operand, report this as an
458909467b48Spatrick   // operand failure.
4590*d415bd75Srobert   if (llvm::count(Match, Match_InvalidOperand) == 1) {
459109467b48Spatrick     return Error(IDLoc, "invalid operand for instruction", EmptyRange,
459209467b48Spatrick                  MatchingInlineAsm);
459309467b48Spatrick   }
459409467b48Spatrick 
4595*d415bd75Srobert   if (llvm::count(Match, Match_InvalidImmUnsignedi4) == 1) {
459609467b48Spatrick     SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
459709467b48Spatrick     if (ErrorLoc == SMLoc())
459809467b48Spatrick       ErrorLoc = IDLoc;
459909467b48Spatrick     return Error(ErrorLoc, "immediate must be an integer in range [0, 15]",
460009467b48Spatrick                  EmptyRange, MatchingInlineAsm);
460109467b48Spatrick   }
460209467b48Spatrick 
460309467b48Spatrick   // If all of these were an outright failure, report it in a useless way.
460409467b48Spatrick   return Error(IDLoc, "unknown instruction mnemonic", EmptyRange,
460509467b48Spatrick                MatchingInlineAsm);
460609467b48Spatrick }
460709467b48Spatrick 
OmitRegisterFromClobberLists(unsigned RegNo)460809467b48Spatrick bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
460909467b48Spatrick   return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
461009467b48Spatrick }
461109467b48Spatrick 
ParseDirective(AsmToken DirectiveID)461209467b48Spatrick bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
461309467b48Spatrick   MCAsmParser &Parser = getParser();
461409467b48Spatrick   StringRef IDVal = DirectiveID.getIdentifier();
461573471bf0Spatrick   if (IDVal.startswith(".arch"))
461673471bf0Spatrick     return parseDirectiveArch();
461709467b48Spatrick   if (IDVal.startswith(".code"))
461809467b48Spatrick     return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
461909467b48Spatrick   else if (IDVal.startswith(".att_syntax")) {
462009467b48Spatrick     if (getLexer().isNot(AsmToken::EndOfStatement)) {
462109467b48Spatrick       if (Parser.getTok().getString() == "prefix")
462209467b48Spatrick         Parser.Lex();
462309467b48Spatrick       else if (Parser.getTok().getString() == "noprefix")
462409467b48Spatrick         return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
462509467b48Spatrick                                            "supported: registers must have a "
462609467b48Spatrick                                            "'%' prefix in .att_syntax");
462709467b48Spatrick     }
462809467b48Spatrick     getParser().setAssemblerDialect(0);
462909467b48Spatrick     return false;
463009467b48Spatrick   } else if (IDVal.startswith(".intel_syntax")) {
463109467b48Spatrick     getParser().setAssemblerDialect(1);
463209467b48Spatrick     if (getLexer().isNot(AsmToken::EndOfStatement)) {
463309467b48Spatrick       if (Parser.getTok().getString() == "noprefix")
463409467b48Spatrick         Parser.Lex();
463509467b48Spatrick       else if (Parser.getTok().getString() == "prefix")
463609467b48Spatrick         return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
463709467b48Spatrick                                            "supported: registers must not have "
463809467b48Spatrick                                            "a '%' prefix in .intel_syntax");
463909467b48Spatrick     }
464009467b48Spatrick     return false;
464173471bf0Spatrick   } else if (IDVal == ".nops")
464273471bf0Spatrick     return parseDirectiveNops(DirectiveID.getLoc());
464373471bf0Spatrick   else if (IDVal == ".even")
464409467b48Spatrick     return parseDirectiveEven(DirectiveID.getLoc());
464509467b48Spatrick   else if (IDVal == ".cv_fpo_proc")
464609467b48Spatrick     return parseDirectiveFPOProc(DirectiveID.getLoc());
464709467b48Spatrick   else if (IDVal == ".cv_fpo_setframe")
464809467b48Spatrick     return parseDirectiveFPOSetFrame(DirectiveID.getLoc());
464909467b48Spatrick   else if (IDVal == ".cv_fpo_pushreg")
465009467b48Spatrick     return parseDirectiveFPOPushReg(DirectiveID.getLoc());
465109467b48Spatrick   else if (IDVal == ".cv_fpo_stackalloc")
465209467b48Spatrick     return parseDirectiveFPOStackAlloc(DirectiveID.getLoc());
465309467b48Spatrick   else if (IDVal == ".cv_fpo_stackalign")
465409467b48Spatrick     return parseDirectiveFPOStackAlign(DirectiveID.getLoc());
465509467b48Spatrick   else if (IDVal == ".cv_fpo_endprologue")
465609467b48Spatrick     return parseDirectiveFPOEndPrologue(DirectiveID.getLoc());
465709467b48Spatrick   else if (IDVal == ".cv_fpo_endproc")
465809467b48Spatrick     return parseDirectiveFPOEndProc(DirectiveID.getLoc());
465973471bf0Spatrick   else if (IDVal == ".seh_pushreg" ||
466073471bf0Spatrick            (Parser.isParsingMasm() && IDVal.equals_insensitive(".pushreg")))
466109467b48Spatrick     return parseDirectiveSEHPushReg(DirectiveID.getLoc());
466273471bf0Spatrick   else if (IDVal == ".seh_setframe" ||
466373471bf0Spatrick            (Parser.isParsingMasm() && IDVal.equals_insensitive(".setframe")))
466409467b48Spatrick     return parseDirectiveSEHSetFrame(DirectiveID.getLoc());
466573471bf0Spatrick   else if (IDVal == ".seh_savereg" ||
466673471bf0Spatrick            (Parser.isParsingMasm() && IDVal.equals_insensitive(".savereg")))
466709467b48Spatrick     return parseDirectiveSEHSaveReg(DirectiveID.getLoc());
466873471bf0Spatrick   else if (IDVal == ".seh_savexmm" ||
466973471bf0Spatrick            (Parser.isParsingMasm() && IDVal.equals_insensitive(".savexmm128")))
467009467b48Spatrick     return parseDirectiveSEHSaveXMM(DirectiveID.getLoc());
467173471bf0Spatrick   else if (IDVal == ".seh_pushframe" ||
467273471bf0Spatrick            (Parser.isParsingMasm() && IDVal.equals_insensitive(".pushframe")))
467309467b48Spatrick     return parseDirectiveSEHPushFrame(DirectiveID.getLoc());
467409467b48Spatrick 
467509467b48Spatrick   return true;
467609467b48Spatrick }
467709467b48Spatrick 
parseDirectiveArch()467873471bf0Spatrick bool X86AsmParser::parseDirectiveArch() {
467973471bf0Spatrick   // Ignore .arch for now.
468073471bf0Spatrick   getParser().parseStringToEndOfStatement();
468173471bf0Spatrick   return false;
468273471bf0Spatrick }
468373471bf0Spatrick 
468473471bf0Spatrick /// parseDirectiveNops
468573471bf0Spatrick ///  ::= .nops size[, control]
parseDirectiveNops(SMLoc L)468673471bf0Spatrick bool X86AsmParser::parseDirectiveNops(SMLoc L) {
468773471bf0Spatrick   int64_t NumBytes = 0, Control = 0;
468873471bf0Spatrick   SMLoc NumBytesLoc, ControlLoc;
4689*d415bd75Srobert   const MCSubtargetInfo& STI = getSTI();
469073471bf0Spatrick   NumBytesLoc = getTok().getLoc();
469173471bf0Spatrick   if (getParser().checkForValidSection() ||
469273471bf0Spatrick       getParser().parseAbsoluteExpression(NumBytes))
469373471bf0Spatrick     return true;
469473471bf0Spatrick 
469573471bf0Spatrick   if (parseOptionalToken(AsmToken::Comma)) {
469673471bf0Spatrick     ControlLoc = getTok().getLoc();
469773471bf0Spatrick     if (getParser().parseAbsoluteExpression(Control))
469873471bf0Spatrick       return true;
469973471bf0Spatrick   }
4700*d415bd75Srobert   if (getParser().parseEOL())
470173471bf0Spatrick     return true;
470273471bf0Spatrick 
470373471bf0Spatrick   if (NumBytes <= 0) {
470473471bf0Spatrick     Error(NumBytesLoc, "'.nops' directive with non-positive size");
470573471bf0Spatrick     return false;
470673471bf0Spatrick   }
470773471bf0Spatrick 
470873471bf0Spatrick   if (Control < 0) {
470973471bf0Spatrick     Error(ControlLoc, "'.nops' directive with negative NOP size");
471073471bf0Spatrick     return false;
471173471bf0Spatrick   }
471273471bf0Spatrick 
471373471bf0Spatrick   /// Emit nops
4714*d415bd75Srobert   getParser().getStreamer().emitNops(NumBytes, Control, L, STI);
471573471bf0Spatrick 
471673471bf0Spatrick   return false;
471773471bf0Spatrick }
471873471bf0Spatrick 
471909467b48Spatrick /// parseDirectiveEven
472009467b48Spatrick ///  ::= .even
parseDirectiveEven(SMLoc L)472109467b48Spatrick bool X86AsmParser::parseDirectiveEven(SMLoc L) {
4722*d415bd75Srobert   if (parseEOL())
472309467b48Spatrick     return false;
472409467b48Spatrick 
472509467b48Spatrick   const MCSection *Section = getStreamer().getCurrentSectionOnly();
472609467b48Spatrick   if (!Section) {
4727*d415bd75Srobert     getStreamer().initSections(false, getSTI());
472809467b48Spatrick     Section = getStreamer().getCurrentSectionOnly();
472909467b48Spatrick   }
4730*d415bd75Srobert   if (Section->useCodeAlign())
4731*d415bd75Srobert     getStreamer().emitCodeAlignment(Align(2), &getSTI(), 0);
473209467b48Spatrick   else
4733*d415bd75Srobert     getStreamer().emitValueToAlignment(Align(2), 0, 1, 0);
473409467b48Spatrick   return false;
473509467b48Spatrick }
473609467b48Spatrick 
473709467b48Spatrick /// ParseDirectiveCode
473809467b48Spatrick ///  ::= .code16 | .code32 | .code64
ParseDirectiveCode(StringRef IDVal,SMLoc L)473909467b48Spatrick bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
474009467b48Spatrick   MCAsmParser &Parser = getParser();
474109467b48Spatrick   Code16GCC = false;
474209467b48Spatrick   if (IDVal == ".code16") {
474309467b48Spatrick     Parser.Lex();
474409467b48Spatrick     if (!is16BitMode()) {
4745*d415bd75Srobert       SwitchMode(X86::Is16Bit);
4746097a140dSpatrick       getParser().getStreamer().emitAssemblerFlag(MCAF_Code16);
474709467b48Spatrick     }
474809467b48Spatrick   } else if (IDVal == ".code16gcc") {
474909467b48Spatrick     // .code16gcc parses as if in 32-bit mode, but emits code in 16-bit mode.
475009467b48Spatrick     Parser.Lex();
475109467b48Spatrick     Code16GCC = true;
475209467b48Spatrick     if (!is16BitMode()) {
4753*d415bd75Srobert       SwitchMode(X86::Is16Bit);
4754097a140dSpatrick       getParser().getStreamer().emitAssemblerFlag(MCAF_Code16);
475509467b48Spatrick     }
475609467b48Spatrick   } else if (IDVal == ".code32") {
475709467b48Spatrick     Parser.Lex();
475809467b48Spatrick     if (!is32BitMode()) {
4759*d415bd75Srobert       SwitchMode(X86::Is32Bit);
4760097a140dSpatrick       getParser().getStreamer().emitAssemblerFlag(MCAF_Code32);
476109467b48Spatrick     }
476209467b48Spatrick   } else if (IDVal == ".code64") {
476309467b48Spatrick     Parser.Lex();
476409467b48Spatrick     if (!is64BitMode()) {
4765*d415bd75Srobert       SwitchMode(X86::Is64Bit);
4766097a140dSpatrick       getParser().getStreamer().emitAssemblerFlag(MCAF_Code64);
476709467b48Spatrick     }
476809467b48Spatrick   } else {
476909467b48Spatrick     Error(L, "unknown directive " + IDVal);
477009467b48Spatrick     return false;
477109467b48Spatrick   }
477209467b48Spatrick 
477309467b48Spatrick   return false;
477409467b48Spatrick }
477509467b48Spatrick 
477609467b48Spatrick // .cv_fpo_proc foo
parseDirectiveFPOProc(SMLoc L)477709467b48Spatrick bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {
477809467b48Spatrick   MCAsmParser &Parser = getParser();
477909467b48Spatrick   StringRef ProcName;
478009467b48Spatrick   int64_t ParamsSize;
478109467b48Spatrick   if (Parser.parseIdentifier(ProcName))
478209467b48Spatrick     return Parser.TokError("expected symbol name");
478309467b48Spatrick   if (Parser.parseIntToken(ParamsSize, "expected parameter byte count"))
478409467b48Spatrick     return true;
478509467b48Spatrick   if (!isUIntN(32, ParamsSize))
478609467b48Spatrick     return Parser.TokError("parameters size out of range");
478773471bf0Spatrick   if (parseEOL())
478873471bf0Spatrick     return true;
478909467b48Spatrick   MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
479009467b48Spatrick   return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
479109467b48Spatrick }
479209467b48Spatrick 
479309467b48Spatrick // .cv_fpo_setframe ebp
parseDirectiveFPOSetFrame(SMLoc L)479409467b48Spatrick bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {
4795*d415bd75Srobert   MCRegister Reg;
479609467b48Spatrick   SMLoc DummyLoc;
4797*d415bd75Srobert   if (parseRegister(Reg, DummyLoc, DummyLoc) || parseEOL())
479873471bf0Spatrick     return true;
479909467b48Spatrick   return getTargetStreamer().emitFPOSetFrame(Reg, L);
480009467b48Spatrick }
480109467b48Spatrick 
480209467b48Spatrick // .cv_fpo_pushreg ebx
parseDirectiveFPOPushReg(SMLoc L)480309467b48Spatrick bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {
4804*d415bd75Srobert   MCRegister Reg;
480509467b48Spatrick   SMLoc DummyLoc;
4806*d415bd75Srobert   if (parseRegister(Reg, DummyLoc, DummyLoc) || parseEOL())
480773471bf0Spatrick     return true;
480809467b48Spatrick   return getTargetStreamer().emitFPOPushReg(Reg, L);
480909467b48Spatrick }
481009467b48Spatrick 
481109467b48Spatrick // .cv_fpo_stackalloc 20
parseDirectiveFPOStackAlloc(SMLoc L)481209467b48Spatrick bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {
481309467b48Spatrick   MCAsmParser &Parser = getParser();
481409467b48Spatrick   int64_t Offset;
481573471bf0Spatrick   if (Parser.parseIntToken(Offset, "expected offset") || parseEOL())
481673471bf0Spatrick     return true;
481709467b48Spatrick   return getTargetStreamer().emitFPOStackAlloc(Offset, L);
481809467b48Spatrick }
481909467b48Spatrick 
482009467b48Spatrick // .cv_fpo_stackalign 8
parseDirectiveFPOStackAlign(SMLoc L)482109467b48Spatrick bool X86AsmParser::parseDirectiveFPOStackAlign(SMLoc L) {
482209467b48Spatrick   MCAsmParser &Parser = getParser();
482309467b48Spatrick   int64_t Offset;
482473471bf0Spatrick   if (Parser.parseIntToken(Offset, "expected offset") || parseEOL())
482573471bf0Spatrick     return true;
482609467b48Spatrick   return getTargetStreamer().emitFPOStackAlign(Offset, L);
482709467b48Spatrick }
482809467b48Spatrick 
482909467b48Spatrick // .cv_fpo_endprologue
parseDirectiveFPOEndPrologue(SMLoc L)483009467b48Spatrick bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {
483109467b48Spatrick   MCAsmParser &Parser = getParser();
483273471bf0Spatrick   if (Parser.parseEOL())
483373471bf0Spatrick     return true;
483409467b48Spatrick   return getTargetStreamer().emitFPOEndPrologue(L);
483509467b48Spatrick }
483609467b48Spatrick 
483709467b48Spatrick // .cv_fpo_endproc
parseDirectiveFPOEndProc(SMLoc L)483809467b48Spatrick bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {
483909467b48Spatrick   MCAsmParser &Parser = getParser();
484073471bf0Spatrick   if (Parser.parseEOL())
484173471bf0Spatrick     return true;
484209467b48Spatrick   return getTargetStreamer().emitFPOEndProc(L);
484309467b48Spatrick }
484409467b48Spatrick 
parseSEHRegisterNumber(unsigned RegClassID,MCRegister & RegNo)484509467b48Spatrick bool X86AsmParser::parseSEHRegisterNumber(unsigned RegClassID,
4846*d415bd75Srobert                                           MCRegister &RegNo) {
484709467b48Spatrick   SMLoc startLoc = getLexer().getLoc();
484809467b48Spatrick   const MCRegisterInfo *MRI = getContext().getRegisterInfo();
484909467b48Spatrick 
485009467b48Spatrick   // Try parsing the argument as a register first.
485109467b48Spatrick   if (getLexer().getTok().isNot(AsmToken::Integer)) {
485209467b48Spatrick     SMLoc endLoc;
4853*d415bd75Srobert     if (parseRegister(RegNo, startLoc, endLoc))
485409467b48Spatrick       return true;
485509467b48Spatrick 
485609467b48Spatrick     if (!X86MCRegisterClasses[RegClassID].contains(RegNo)) {
485709467b48Spatrick       return Error(startLoc,
485809467b48Spatrick                    "register is not supported for use with this directive");
485909467b48Spatrick     }
486009467b48Spatrick   } else {
486109467b48Spatrick     // Otherwise, an integer number matching the encoding of the desired
486209467b48Spatrick     // register may appear.
486309467b48Spatrick     int64_t EncodedReg;
486409467b48Spatrick     if (getParser().parseAbsoluteExpression(EncodedReg))
486509467b48Spatrick       return true;
486609467b48Spatrick 
486709467b48Spatrick     // The SEH register number is the same as the encoding register number. Map
486809467b48Spatrick     // from the encoding back to the LLVM register number.
486909467b48Spatrick     RegNo = 0;
487009467b48Spatrick     for (MCPhysReg Reg : X86MCRegisterClasses[RegClassID]) {
487109467b48Spatrick       if (MRI->getEncodingValue(Reg) == EncodedReg) {
487209467b48Spatrick         RegNo = Reg;
487309467b48Spatrick         break;
487409467b48Spatrick       }
487509467b48Spatrick     }
487609467b48Spatrick     if (RegNo == 0) {
487709467b48Spatrick       return Error(startLoc,
487809467b48Spatrick                    "incorrect register number for use with this directive");
487909467b48Spatrick     }
488009467b48Spatrick   }
488109467b48Spatrick 
488209467b48Spatrick   return false;
488309467b48Spatrick }
488409467b48Spatrick 
parseDirectiveSEHPushReg(SMLoc Loc)488509467b48Spatrick bool X86AsmParser::parseDirectiveSEHPushReg(SMLoc Loc) {
4886*d415bd75Srobert   MCRegister Reg;
488709467b48Spatrick   if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg))
488809467b48Spatrick     return true;
488909467b48Spatrick 
489009467b48Spatrick   if (getLexer().isNot(AsmToken::EndOfStatement))
4891*d415bd75Srobert     return TokError("expected end of directive");
489209467b48Spatrick 
489309467b48Spatrick   getParser().Lex();
4894*d415bd75Srobert   getStreamer().emitWinCFIPushReg(Reg, Loc);
489509467b48Spatrick   return false;
489609467b48Spatrick }
489709467b48Spatrick 
parseDirectiveSEHSetFrame(SMLoc Loc)489809467b48Spatrick bool X86AsmParser::parseDirectiveSEHSetFrame(SMLoc Loc) {
4899*d415bd75Srobert   MCRegister Reg;
490009467b48Spatrick   int64_t Off;
490109467b48Spatrick   if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg))
490209467b48Spatrick     return true;
490309467b48Spatrick   if (getLexer().isNot(AsmToken::Comma))
490409467b48Spatrick     return TokError("you must specify a stack pointer offset");
490509467b48Spatrick 
490609467b48Spatrick   getParser().Lex();
490709467b48Spatrick   if (getParser().parseAbsoluteExpression(Off))
490809467b48Spatrick     return true;
490909467b48Spatrick 
491009467b48Spatrick   if (getLexer().isNot(AsmToken::EndOfStatement))
4911*d415bd75Srobert     return TokError("expected end of directive");
491209467b48Spatrick 
491309467b48Spatrick   getParser().Lex();
4914*d415bd75Srobert   getStreamer().emitWinCFISetFrame(Reg, Off, Loc);
491509467b48Spatrick   return false;
491609467b48Spatrick }
491709467b48Spatrick 
parseDirectiveSEHSaveReg(SMLoc Loc)491809467b48Spatrick bool X86AsmParser::parseDirectiveSEHSaveReg(SMLoc Loc) {
4919*d415bd75Srobert   MCRegister Reg;
492009467b48Spatrick   int64_t Off;
492109467b48Spatrick   if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg))
492209467b48Spatrick     return true;
492309467b48Spatrick   if (getLexer().isNot(AsmToken::Comma))
492409467b48Spatrick     return TokError("you must specify an offset on the stack");
492509467b48Spatrick 
492609467b48Spatrick   getParser().Lex();
492709467b48Spatrick   if (getParser().parseAbsoluteExpression(Off))
492809467b48Spatrick     return true;
492909467b48Spatrick 
493009467b48Spatrick   if (getLexer().isNot(AsmToken::EndOfStatement))
4931*d415bd75Srobert     return TokError("expected end of directive");
493209467b48Spatrick 
493309467b48Spatrick   getParser().Lex();
4934*d415bd75Srobert   getStreamer().emitWinCFISaveReg(Reg, Off, Loc);
493509467b48Spatrick   return false;
493609467b48Spatrick }
493709467b48Spatrick 
parseDirectiveSEHSaveXMM(SMLoc Loc)493809467b48Spatrick bool X86AsmParser::parseDirectiveSEHSaveXMM(SMLoc Loc) {
4939*d415bd75Srobert   MCRegister Reg;
494009467b48Spatrick   int64_t Off;
494109467b48Spatrick   if (parseSEHRegisterNumber(X86::VR128XRegClassID, Reg))
494209467b48Spatrick     return true;
494309467b48Spatrick   if (getLexer().isNot(AsmToken::Comma))
494409467b48Spatrick     return TokError("you must specify an offset on the stack");
494509467b48Spatrick 
494609467b48Spatrick   getParser().Lex();
494709467b48Spatrick   if (getParser().parseAbsoluteExpression(Off))
494809467b48Spatrick     return true;
494909467b48Spatrick 
495009467b48Spatrick   if (getLexer().isNot(AsmToken::EndOfStatement))
4951*d415bd75Srobert     return TokError("expected end of directive");
495209467b48Spatrick 
495309467b48Spatrick   getParser().Lex();
4954*d415bd75Srobert   getStreamer().emitWinCFISaveXMM(Reg, Off, Loc);
495509467b48Spatrick   return false;
495609467b48Spatrick }
495709467b48Spatrick 
parseDirectiveSEHPushFrame(SMLoc Loc)495809467b48Spatrick bool X86AsmParser::parseDirectiveSEHPushFrame(SMLoc Loc) {
495909467b48Spatrick   bool Code = false;
496009467b48Spatrick   StringRef CodeID;
496109467b48Spatrick   if (getLexer().is(AsmToken::At)) {
496209467b48Spatrick     SMLoc startLoc = getLexer().getLoc();
496309467b48Spatrick     getParser().Lex();
496409467b48Spatrick     if (!getParser().parseIdentifier(CodeID)) {
496509467b48Spatrick       if (CodeID != "code")
496609467b48Spatrick         return Error(startLoc, "expected @code");
496709467b48Spatrick       Code = true;
496809467b48Spatrick     }
496909467b48Spatrick   }
497009467b48Spatrick 
497109467b48Spatrick   if (getLexer().isNot(AsmToken::EndOfStatement))
4972*d415bd75Srobert     return TokError("expected end of directive");
497309467b48Spatrick 
497409467b48Spatrick   getParser().Lex();
4975*d415bd75Srobert   getStreamer().emitWinCFIPushFrame(Code, Loc);
497609467b48Spatrick   return false;
497709467b48Spatrick }
497809467b48Spatrick 
497909467b48Spatrick // Force static initialization.
LLVMInitializeX86AsmParser()498009467b48Spatrick extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeX86AsmParser() {
498109467b48Spatrick   RegisterMCAsmParser<X86AsmParser> X(getTheX86_32Target());
498209467b48Spatrick   RegisterMCAsmParser<X86AsmParser> Y(getTheX86_64Target());
498309467b48Spatrick }
498409467b48Spatrick 
498509467b48Spatrick #define GET_REGISTER_MATCHER
498609467b48Spatrick #define GET_MATCHER_IMPLEMENTATION
498709467b48Spatrick #define GET_SUBTARGET_FEATURE_NAME
498809467b48Spatrick #include "X86GenAsmMatcher.inc"
4989