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