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