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