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