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 != "setb" && PatchedName != "setnb")
3291 PatchedName = PatchedName.substr(0, Name.size()-1);
3292
3293 unsigned ComparisonPredicate = ~0U;
3294
3295 // FIXME: Hack to recognize cmp<comparison code>{sh,ss,sd,ph,ps,pd}.
3296 if ((PatchedName.starts_with("cmp") || PatchedName.starts_with("vcmp")) &&
3297 (PatchedName.ends_with("ss") || PatchedName.ends_with("sd") ||
3298 PatchedName.ends_with("sh") || PatchedName.ends_with("ph") ||
3299 PatchedName.ends_with("ps") || PatchedName.ends_with("pd"))) {
3300 bool IsVCMP = PatchedName[0] == 'v';
3301 unsigned CCIdx = IsVCMP ? 4 : 3;
3302 unsigned CC = StringSwitch<unsigned>(
3303 PatchedName.slice(CCIdx, PatchedName.size() - 2))
3304 .Case("eq", 0x00)
3305 .Case("eq_oq", 0x00)
3306 .Case("lt", 0x01)
3307 .Case("lt_os", 0x01)
3308 .Case("le", 0x02)
3309 .Case("le_os", 0x02)
3310 .Case("unord", 0x03)
3311 .Case("unord_q", 0x03)
3312 .Case("neq", 0x04)
3313 .Case("neq_uq", 0x04)
3314 .Case("nlt", 0x05)
3315 .Case("nlt_us", 0x05)
3316 .Case("nle", 0x06)
3317 .Case("nle_us", 0x06)
3318 .Case("ord", 0x07)
3319 .Case("ord_q", 0x07)
3320 /* AVX only from here */
3321 .Case("eq_uq", 0x08)
3322 .Case("nge", 0x09)
3323 .Case("nge_us", 0x09)
3324 .Case("ngt", 0x0A)
3325 .Case("ngt_us", 0x0A)
3326 .Case("false", 0x0B)
3327 .Case("false_oq", 0x0B)
3328 .Case("neq_oq", 0x0C)
3329 .Case("ge", 0x0D)
3330 .Case("ge_os", 0x0D)
3331 .Case("gt", 0x0E)
3332 .Case("gt_os", 0x0E)
3333 .Case("true", 0x0F)
3334 .Case("true_uq", 0x0F)
3335 .Case("eq_os", 0x10)
3336 .Case("lt_oq", 0x11)
3337 .Case("le_oq", 0x12)
3338 .Case("unord_s", 0x13)
3339 .Case("neq_us", 0x14)
3340 .Case("nlt_uq", 0x15)
3341 .Case("nle_uq", 0x16)
3342 .Case("ord_s", 0x17)
3343 .Case("eq_us", 0x18)
3344 .Case("nge_uq", 0x19)
3345 .Case("ngt_uq", 0x1A)
3346 .Case("false_os", 0x1B)
3347 .Case("neq_os", 0x1C)
3348 .Case("ge_oq", 0x1D)
3349 .Case("gt_oq", 0x1E)
3350 .Case("true_us", 0x1F)
3351 .Default(~0U);
3352 if (CC != ~0U && (IsVCMP || CC < 8) &&
3353 (IsVCMP || PatchedName.back() != 'h')) {
3354 if (PatchedName.ends_with("ss"))
3355 PatchedName = IsVCMP ? "vcmpss" : "cmpss";
3356 else if (PatchedName.ends_with("sd"))
3357 PatchedName = IsVCMP ? "vcmpsd" : "cmpsd";
3358 else if (PatchedName.ends_with("ps"))
3359 PatchedName = IsVCMP ? "vcmpps" : "cmpps";
3360 else if (PatchedName.ends_with("pd"))
3361 PatchedName = IsVCMP ? "vcmppd" : "cmppd";
3362 else if (PatchedName.ends_with("sh"))
3363 PatchedName = "vcmpsh";
3364 else if (PatchedName.ends_with("ph"))
3365 PatchedName = "vcmpph";
3366 else
3367 llvm_unreachable("Unexpected suffix!");
3368
3369 ComparisonPredicate = CC;
3370 }
3371 }
3372
3373 // FIXME: Hack to recognize vpcmp<comparison code>{ub,uw,ud,uq,b,w,d,q}.
3374 if (PatchedName.starts_with("vpcmp") &&
3375 (PatchedName.back() == 'b' || PatchedName.back() == 'w' ||
3376 PatchedName.back() == 'd' || PatchedName.back() == 'q')) {
3377 unsigned SuffixSize = PatchedName.drop_back().back() == 'u' ? 2 : 1;
3378 unsigned CC = StringSwitch<unsigned>(
3379 PatchedName.slice(5, PatchedName.size() - SuffixSize))
3380 .Case("eq", 0x0) // Only allowed on unsigned. Checked below.
3381 .Case("lt", 0x1)
3382 .Case("le", 0x2)
3383 //.Case("false", 0x3) // Not a documented alias.
3384 .Case("neq", 0x4)
3385 .Case("nlt", 0x5)
3386 .Case("nle", 0x6)
3387 //.Case("true", 0x7) // Not a documented alias.
3388 .Default(~0U);
3389 if (CC != ~0U && (CC != 0 || SuffixSize == 2)) {
3390 switch (PatchedName.back()) {
3391 default: llvm_unreachable("Unexpected character!");
3392 case 'b': PatchedName = SuffixSize == 2 ? "vpcmpub" : "vpcmpb"; break;
3393 case 'w': PatchedName = SuffixSize == 2 ? "vpcmpuw" : "vpcmpw"; break;
3394 case 'd': PatchedName = SuffixSize == 2 ? "vpcmpud" : "vpcmpd"; break;
3395 case 'q': PatchedName = SuffixSize == 2 ? "vpcmpuq" : "vpcmpq"; break;
3396 }
3397 // Set up the immediate to push into the operands later.
3398 ComparisonPredicate = CC;
3399 }
3400 }
3401
3402 // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}.
3403 if (PatchedName.starts_with("vpcom") &&
3404 (PatchedName.back() == 'b' || PatchedName.back() == 'w' ||
3405 PatchedName.back() == 'd' || PatchedName.back() == 'q')) {
3406 unsigned SuffixSize = PatchedName.drop_back().back() == 'u' ? 2 : 1;
3407 unsigned CC = StringSwitch<unsigned>(
3408 PatchedName.slice(5, PatchedName.size() - SuffixSize))
3409 .Case("lt", 0x0)
3410 .Case("le", 0x1)
3411 .Case("gt", 0x2)
3412 .Case("ge", 0x3)
3413 .Case("eq", 0x4)
3414 .Case("neq", 0x5)
3415 .Case("false", 0x6)
3416 .Case("true", 0x7)
3417 .Default(~0U);
3418 if (CC != ~0U) {
3419 switch (PatchedName.back()) {
3420 default: llvm_unreachable("Unexpected character!");
3421 case 'b': PatchedName = SuffixSize == 2 ? "vpcomub" : "vpcomb"; break;
3422 case 'w': PatchedName = SuffixSize == 2 ? "vpcomuw" : "vpcomw"; break;
3423 case 'd': PatchedName = SuffixSize == 2 ? "vpcomud" : "vpcomd"; break;
3424 case 'q': PatchedName = SuffixSize == 2 ? "vpcomuq" : "vpcomq"; break;
3425 }
3426 // Set up the immediate to push into the operands later.
3427 ComparisonPredicate = CC;
3428 }
3429 }
3430
3431 // Determine whether this is an instruction prefix.
3432 // FIXME:
3433 // Enhance prefixes integrity robustness. for example, following forms
3434 // are currently tolerated:
3435 // repz repnz <insn> ; GAS errors for the use of two similar prefixes
3436 // lock addq %rax, %rbx ; Destination operand must be of memory type
3437 // xacquire <insn> ; xacquire must be accompanied by 'lock'
3438 bool IsPrefix =
3440 .Cases("cs", "ds", "es", "fs", "gs", "ss", true)
3441 .Cases("rex64", "data32", "data16", "addr32", "addr16", true)
3442 .Cases("xacquire", "xrelease", true)
3443 .Cases("acquire", "release", isParsingIntelSyntax())
3444 .Default(false);
3445
3446 auto isLockRepeatNtPrefix = [](StringRef N) {
3447 return StringSwitch<bool>(N)
3448 .Cases("lock", "rep", "repe", "repz", "repne", "repnz", "notrack", true)
3449 .Default(false);
3450 };
3451
3452 bool CurlyAsEndOfStatement = false;
3453
3454 unsigned Flags = X86::IP_NO_PREFIX;
3455 while (isLockRepeatNtPrefix(Name.lower())) {
3456 unsigned Prefix =
3458 .Cases("lock", "lock", X86::IP_HAS_LOCK)
3459 .Cases("rep", "repe", "repz", X86::IP_HAS_REPEAT)
3460 .Cases("repne", "repnz", X86::IP_HAS_REPEAT_NE)
3461 .Cases("notrack", "notrack", X86::IP_HAS_NOTRACK)
3462 .Default(X86::IP_NO_PREFIX); // Invalid prefix (impossible)
3463 Flags |= Prefix;
3464 if (getLexer().is(AsmToken::EndOfStatement)) {
3465 // We don't have real instr with the given prefix
3466 // let's use the prefix as the instr.
3467 // TODO: there could be several prefixes one after another
3469 break;
3470 }
3471 // FIXME: The mnemonic won't match correctly if its not in lower case.
3472 Name = Parser.getTok().getString();
3473 Parser.Lex(); // eat the prefix
3474 // Hack: we could have something like "rep # some comment" or
3475 // "lock; cmpxchg16b $1" or "lock\0A\09incl" or "lock/incl"
3476 while (Name.starts_with(";") || Name.starts_with("\n") ||
3477 Name.starts_with("#") || Name.starts_with("\t") ||
3478 Name.starts_with("/")) {
3479 // FIXME: The mnemonic won't match correctly if its not in lower case.
3480 Name = Parser.getTok().getString();
3481 Parser.Lex(); // go to next prefix or instr
3482 }
3483 }
3484
3485 if (Flags)
3486 PatchedName = Name;
3487
3488 // Hacks to handle 'data16' and 'data32'
3489 if (PatchedName == "data16" && is16BitMode()) {
3490 return Error(NameLoc, "redundant data16 prefix");
3491 }
3492 if (PatchedName == "data32") {
3493 if (is32BitMode())
3494 return Error(NameLoc, "redundant data32 prefix");
3495 if (is64BitMode())
3496 return Error(NameLoc, "'data32' is not supported in 64-bit mode");
3497 // Hack to 'data16' for the table lookup.
3498 PatchedName = "data16";
3499
3500 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3501 StringRef Next = Parser.getTok().getString();
3502 getLexer().Lex();
3503 // data32 effectively changes the instruction suffix.
3504 // TODO Generalize.
3505 if (Next == "callw")
3506 Next = "calll";
3507 if (Next == "ljmpw")
3508 Next = "ljmpl";
3509
3510 Name = Next;
3511 PatchedName = Name;
3512 ForcedDataPrefix = X86::Is32Bit;
3513 IsPrefix = false;
3514 }
3515 }
3516
3517 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
3518
3519 // Push the immediate if we extracted one from the mnemonic.
3520 if (ComparisonPredicate != ~0U && !isParsingIntelSyntax()) {
3521 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonPredicate,
3522 getParser().getContext());
3523 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
3524 }
3525
3526 // Parse condtional flags after mnemonic.
3527 if ((Name.starts_with("ccmp") || Name.starts_with("ctest")) &&
3528 parseCFlagsOp(Operands))
3529 return true;
3530
3531 // This does the actual operand parsing. Don't parse any more if we have a
3532 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
3533 // just want to parse the "lock" as the first instruction and the "incl" as
3534 // the next one.
3535 if (getLexer().isNot(AsmToken::EndOfStatement) && !IsPrefix) {
3536 // Parse '*' modifier.
3537 if (getLexer().is(AsmToken::Star))
3538 Operands.push_back(X86Operand::CreateToken("*", consumeToken()));
3539
3540 // Read the operands.
3541 while (true) {
3542 if (parseOperand(Operands, Name))
3543 return true;
3544 if (HandleAVX512Operand(Operands))
3545 return true;
3546
3547 // check for comma and eat it
3548 if (getLexer().is(AsmToken::Comma))
3549 Parser.Lex();
3550 else
3551 break;
3552 }
3553
3554 // In MS inline asm curly braces mark the beginning/end of a block,
3555 // therefore they should be interepreted as end of statement
3556 CurlyAsEndOfStatement =
3557 isParsingIntelSyntax() && isParsingMSInlineAsm() &&
3558 (getLexer().is(AsmToken::LCurly) || getLexer().is(AsmToken::RCurly));
3559 if (getLexer().isNot(AsmToken::EndOfStatement) && !CurlyAsEndOfStatement)
3560 return TokError("unexpected token in argument list");
3561 }
3562
3563 // Push the immediate if we extracted one from the mnemonic.
3564 if (ComparisonPredicate != ~0U && isParsingIntelSyntax()) {
3565 const MCExpr *ImmOp = MCConstantExpr::create(ComparisonPredicate,
3566 getParser().getContext());
3567 Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc));
3568 }
3569
3570 // Consume the EndOfStatement or the prefix separator Slash
3571 if (getLexer().is(AsmToken::EndOfStatement) ||
3572 (IsPrefix && getLexer().is(AsmToken::Slash)))
3573 Parser.Lex();
3574 else if (CurlyAsEndOfStatement)
3575 // Add an actual EndOfStatement before the curly brace
3576 Info.AsmRewrites->emplace_back(AOK_EndOfStatement,
3577 getLexer().getTok().getLoc(), 0);
3578
3579 // This is for gas compatibility and cannot be done in td.
3580 // Adding "p" for some floating point with no argument.
3581 // For example: fsub --> fsubp
3582 bool IsFp =
3583 Name == "fsub" || Name == "fdiv" || Name == "fsubr" || Name == "fdivr";
3584 if (IsFp && Operands.size() == 1) {
3585 const char *Repl = StringSwitch<const char *>(Name)
3586 .Case("fsub", "fsubp")
3587 .Case("fdiv", "fdivp")
3588 .Case("fsubr", "fsubrp")
3589 .Case("fdivr", "fdivrp");
3590 static_cast<X86Operand &>(*Operands[0]).setTokenValue(Repl);
3591 }
3592
3593 if ((Name == "mov" || Name == "movw" || Name == "movl") &&
3594 (Operands.size() == 3)) {
3595 X86Operand &Op1 = (X86Operand &)*Operands[1];
3596 X86Operand &Op2 = (X86Operand &)*Operands[2];
3597 SMLoc Loc = Op1.getEndLoc();
3598 // Moving a 32 or 16 bit value into a segment register has the same
3599 // behavior. Modify such instructions to always take shorter form.
3600 if (Op1.isReg() && Op2.isReg() &&
3601 X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
3602 Op2.getReg()) &&
3603 (X86MCRegisterClasses[X86::GR16RegClassID].contains(Op1.getReg()) ||
3604 X86MCRegisterClasses[X86::GR32RegClassID].contains(Op1.getReg()))) {
3605 // Change instruction name to match new instruction.
3606 if (Name != "mov" && Name[3] == (is16BitMode() ? 'l' : 'w')) {
3607 Name = is16BitMode() ? "movw" : "movl";
3608 Operands[0] = X86Operand::CreateToken(Name, NameLoc);
3609 }
3610 // Select the correct equivalent 16-/32-bit source register.
3611 MCRegister Reg =
3612 getX86SubSuperRegister(Op1.getReg(), is16BitMode() ? 16 : 32);
3613 Operands[1] = X86Operand::CreateReg(Reg, Loc, Loc);
3614 }
3615 }
3616
3617 // This is a terrible hack to handle "out[s]?[bwl]? %al, (%dx)" ->
3618 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
3619 // documented form in various unofficial manuals, so a lot of code uses it.
3620 if ((Name == "outb" || Name == "outsb" || Name == "outw" || Name == "outsw" ||
3621 Name == "outl" || Name == "outsl" || Name == "out" || Name == "outs") &&
3622 Operands.size() == 3) {
3623 X86Operand &Op = (X86Operand &)*Operands.back();
3624 if (Op.isDXReg())
3625 Operands.back() = X86Operand::CreateReg(X86::DX, Op.getStartLoc(),
3626 Op.getEndLoc());
3627 }
3628 // Same hack for "in[s]?[bwl]? (%dx), %al" -> "inb %dx, %al".
3629 if ((Name == "inb" || Name == "insb" || Name == "inw" || Name == "insw" ||
3630 Name == "inl" || Name == "insl" || Name == "in" || Name == "ins") &&
3631 Operands.size() == 3) {
3632 X86Operand &Op = (X86Operand &)*Operands[1];
3633 if (Op.isDXReg())
3634 Operands[1] = X86Operand::CreateReg(X86::DX, Op.getStartLoc(),
3635 Op.getEndLoc());
3636 }
3637
3639 bool HadVerifyError = false;
3640
3641 // Append default arguments to "ins[bwld]"
3642 if (Name.starts_with("ins") &&
3643 (Operands.size() == 1 || Operands.size() == 3) &&
3644 (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd" ||
3645 Name == "ins")) {
3646
3647 AddDefaultSrcDestOperands(TmpOperands,
3648 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc),
3649 DefaultMemDIOperand(NameLoc));
3650 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3651 }
3652
3653 // Append default arguments to "outs[bwld]"
3654 if (Name.starts_with("outs") &&
3655 (Operands.size() == 1 || Operands.size() == 3) &&
3656 (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
3657 Name == "outsd" || Name == "outs")) {
3658 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3659 X86Operand::CreateReg(X86::DX, NameLoc, NameLoc));
3660 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3661 }
3662
3663 // Transform "lods[bwlq]" into "lods[bwlq] ($SIREG)" for appropriate
3664 // values of $SIREG according to the mode. It would be nice if this
3665 // could be achieved with InstAlias in the tables.
3666 if (Name.starts_with("lods") &&
3667 (Operands.size() == 1 || Operands.size() == 2) &&
3668 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
3669 Name == "lodsl" || Name == "lodsd" || Name == "lodsq")) {
3670 TmpOperands.push_back(DefaultMemSIOperand(NameLoc));
3671 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3672 }
3673
3674 // Transform "stos[bwlq]" into "stos[bwlq] ($DIREG)" for appropriate
3675 // values of $DIREG according to the mode. It would be nice if this
3676 // could be achieved with InstAlias in the tables.
3677 if (Name.starts_with("stos") &&
3678 (Operands.size() == 1 || Operands.size() == 2) &&
3679 (Name == "stos" || Name == "stosb" || Name == "stosw" ||
3680 Name == "stosl" || Name == "stosd" || Name == "stosq")) {
3681 TmpOperands.push_back(DefaultMemDIOperand(NameLoc));
3682 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3683 }
3684
3685 // Transform "scas[bwlq]" into "scas[bwlq] ($DIREG)" for appropriate
3686 // values of $DIREG according to the mode. It would be nice if this
3687 // could be achieved with InstAlias in the tables.
3688 if (Name.starts_with("scas") &&
3689 (Operands.size() == 1 || Operands.size() == 2) &&
3690 (Name == "scas" || Name == "scasb" || Name == "scasw" ||
3691 Name == "scasl" || Name == "scasd" || Name == "scasq")) {
3692 TmpOperands.push_back(DefaultMemDIOperand(NameLoc));
3693 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3694 }
3695
3696 // Add default SI and DI operands to "cmps[bwlq]".
3697 if (Name.starts_with("cmps") &&
3698 (Operands.size() == 1 || Operands.size() == 3) &&
3699 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
3700 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
3701 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
3702 DefaultMemSIOperand(NameLoc));
3703 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3704 }
3705
3706 // Add default SI and DI operands to "movs[bwlq]".
3707 if (((Name.starts_with("movs") &&
3708 (Name == "movs" || Name == "movsb" || Name == "movsw" ||
3709 Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
3710 (Name.starts_with("smov") &&
3711 (Name == "smov" || Name == "smovb" || Name == "smovw" ||
3712 Name == "smovl" || Name == "smovd" || Name == "smovq"))) &&
3713 (Operands.size() == 1 || Operands.size() == 3)) {
3714 if (Name == "movsd" && Operands.size() == 1 && !isParsingIntelSyntax())
3715 Operands.back() = X86Operand::CreateToken("movsl", NameLoc);
3716 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3717 DefaultMemDIOperand(NameLoc));
3718 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3719 }
3720
3721 // Check if we encountered an error for one the string insturctions
3722 if (HadVerifyError) {
3723 return HadVerifyError;
3724 }
3725
3726 // Transforms "xlat mem8" into "xlatb"
3727 if ((Name == "xlat" || Name == "xlatb") && Operands.size() == 2) {
3728 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
3729 if (Op1.isMem8()) {
3730 Warning(Op1.getStartLoc(), "memory operand is only for determining the "
3731 "size, (R|E)BX will be used for the location");
3732 Operands.pop_back();
3733 static_cast<X86Operand &>(*Operands[0]).setTokenValue("xlatb");
3734 }
3735 }
3736
3737 if (Flags)
3738 Operands.push_back(X86Operand::CreatePrefix(Flags, NameLoc, NameLoc));
3739 return false;
3740}
3741
3742bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
3743 if (ForcedVEXEncoding != VEXEncoding_VEX3 &&
3744 X86::optimizeInstFromVEX3ToVEX2(Inst, MII.get(Inst.getOpcode())))
3745 return true;
3746
3748 return true;
3749
3750 switch (Inst.getOpcode()) {
3751 default: return false;
3752 case X86::JMP_1:
3753 // {disp32} forces a larger displacement as if the instruction was relaxed.
3754 // NOTE: 16-bit mode uses 16-bit displacement even though it says {disp32}.
3755 // This matches GNU assembler.
3756 if (ForcedDispEncoding == DispEncoding_Disp32) {
3757 Inst.setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);
3758 return true;
3759 }
3760
3761 return false;
3762 case X86::JCC_1:
3763 // {disp32} forces a larger displacement as if the instruction was relaxed.
3764 // NOTE: 16-bit mode uses 16-bit displacement even though it says {disp32}.
3765 // This matches GNU assembler.
3766 if (ForcedDispEncoding == DispEncoding_Disp32) {
3767 Inst.setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);
3768 return true;
3769 }
3770
3771 return false;
3772 case X86::INT: {
3773 // Transforms "int $3" into "int3" as a size optimization.
3774 // We can't write this as an InstAlias.
3775 if (!Inst.getOperand(0).isImm() || Inst.getOperand(0).getImm() != 3)
3776 return false;
3777 Inst.clear();
3778 Inst.setOpcode(X86::INT3);
3779 return true;
3780 }
3781 }
3782}
3783
3784bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
3785 using namespace X86;
3786 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
3787 unsigned Opcode = Inst.getOpcode();
3788 uint64_t TSFlags = MII.get(Opcode).TSFlags;
3789 if (isVFCMADDCPH(Opcode) || isVFCMADDCSH(Opcode) || isVFMADDCPH(Opcode) ||
3790 isVFMADDCSH(Opcode)) {
3791 unsigned Dest = Inst.getOperand(0).getReg();
3792 for (unsigned i = 2; i < Inst.getNumOperands(); i++)
3793 if (Inst.getOperand(i).isReg() && Dest == Inst.getOperand(i).getReg())
3794 return Warning(Ops[0]->getStartLoc(), "Destination register should be "
3795 "distinct from source registers");
3796 } else if (isVFCMULCPH(Opcode) || isVFCMULCSH(Opcode) || isVFMULCPH(Opcode) ||
3797 isVFMULCSH(Opcode)) {
3798 unsigned Dest = Inst.getOperand(0).getReg();
3799 // The mask variants have different operand list. Scan from the third
3800 // operand to avoid emitting incorrect warning.
3801 // VFMULCPHZrr Dest, Src1, Src2
3802 // VFMULCPHZrrk Dest, Dest, Mask, Src1, Src2
3803 // VFMULCPHZrrkz Dest, Mask, Src1, Src2
3804 for (unsigned i = TSFlags & X86II::EVEX_K ? 2 : 1;
3805 i < Inst.getNumOperands(); i++)
3806 if (Inst.getOperand(i).isReg() && Dest == Inst.getOperand(i).getReg())
3807 return Warning(Ops[0]->getStartLoc(), "Destination register should be "
3808 "distinct from source registers");
3809 } else if (isV4FMADDPS(Opcode) || isV4FMADDSS(Opcode) ||
3810 isV4FNMADDPS(Opcode) || isV4FNMADDSS(Opcode) ||
3811 isVP4DPWSSDS(Opcode) || isVP4DPWSSD(Opcode)) {
3812 unsigned Src2 = Inst.getOperand(Inst.getNumOperands() -
3814 unsigned Src2Enc = MRI->getEncodingValue(Src2);
3815 if (Src2Enc % 4 != 0) {
3817 unsigned GroupStart = (Src2Enc / 4) * 4;
3818 unsigned GroupEnd = GroupStart + 3;
3819 return Warning(Ops[0]->getStartLoc(),
3820 "source register '" + RegName + "' implicitly denotes '" +
3821 RegName.take_front(3) + Twine(GroupStart) + "' to '" +
3822 RegName.take_front(3) + Twine(GroupEnd) +
3823 "' source group");
3824 }
3825 } else if (isVGATHERDPD(Opcode) || isVGATHERDPS(Opcode) ||
3826 isVGATHERQPD(Opcode) || isVGATHERQPS(Opcode) ||
3827 isVPGATHERDD(Opcode) || isVPGATHERDQ(Opcode) ||
3828 isVPGATHERQD(Opcode) || isVPGATHERQQ(Opcode)) {
3829 bool HasEVEX = (TSFlags & X86II::EncodingMask) == X86II::EVEX;
3830 if (HasEVEX) {
3831 unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg());
3832 unsigned Index = MRI->getEncodingValue(
3833 Inst.getOperand(4 + X86::AddrIndexReg).getReg());
3834 if (Dest == Index)
3835 return Warning(Ops[0]->getStartLoc(), "index and destination registers "
3836 "should be distinct");
3837 } else {
3838 unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg());
3839 unsigned Mask = MRI->getEncodingValue(Inst.getOperand(1).getReg());
3840 unsigned Index = MRI->getEncodingValue(
3841 Inst.getOperand(3 + X86::AddrIndexReg).getReg());
3842 if (Dest == Mask || Dest == Index || Mask == Index)
3843 return Warning(Ops[0]->getStartLoc(), "mask, index, and destination "
3844 "registers should be distinct");
3845 }
3846 }
3847
3848 // Check that we aren't mixing AH/BH/CH/DH with REX prefix. We only need to
3849 // check this with the legacy encoding, VEX/EVEX/XOP don't use REX.
3850 if ((TSFlags & X86II::EncodingMask) == 0) {
3851 MCPhysReg HReg = X86::NoRegister;
3852 bool UsesRex = TSFlags & X86II::REX_W;
3853 unsigned NumOps = Inst.getNumOperands();
3854 for (unsigned i = 0; i != NumOps; ++i) {
3855 const MCOperand &MO = Inst.getOperand(i);
3856 if (!MO.isReg())
3857 continue;
3858 unsigned Reg = MO.getReg();
3859 if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH)
3860 HReg = Reg;
3863 UsesRex = true;
3864 }
3865
3866 if (UsesRex && HReg != X86::NoRegister) {
3868 return Error(Ops[0]->getStartLoc(),
3869 "can't encode '" + RegName + "' in an instruction requiring "
3870 "REX prefix");
3871 }
3872 }
3873
3874 if ((Opcode == X86::PREFETCHIT0 || Opcode == X86::PREFETCHIT1)) {
3875 const MCOperand &MO = Inst.getOperand(X86::AddrBaseReg);
3876 if (!MO.isReg() || MO.getReg() != X86::RIP)
3877 return Warning(
3878 Ops[0]->getStartLoc(),
3879 Twine((Inst.getOpcode() == X86::PREFETCHIT0 ? "'prefetchit0'"
3880 : "'prefetchit1'")) +
3881 " only supports RIP-relative address");
3882 }
3883 return false;
3884}
3885
3886void X86AsmParser::emitWarningForSpecialLVIInstruction(SMLoc Loc) {
3887 Warning(Loc, "Instruction may be vulnerable to LVI and "
3888 "requires manual mitigation");
3889 Note(SMLoc(), "See https://software.intel.com/"
3890 "security-software-guidance/insights/"
3891 "deep-dive-load-value-injection#specialinstructions"
3892 " for more information");
3893}
3894
3895/// RET instructions and also instructions that indirect calls/jumps from memory
3896/// combine a load and a branch within a single instruction. To mitigate these
3897/// instructions against LVI, they must be decomposed into separate load and
3898/// branch instructions, with an LFENCE in between. For more details, see:
3899/// - X86LoadValueInjectionRetHardening.cpp
3900/// - X86LoadValueInjectionIndirectThunks.cpp
3901/// - https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection
3902///
3903/// Returns `true` if a mitigation was applied or warning was emitted.
3904void X86AsmParser::applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out) {
3905 // Information on control-flow instructions that require manual mitigation can
3906 // be found here:
3907 // https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection#specialinstructions
3908 switch (Inst.getOpcode()) {
3909 case X86::RET16:
3910 case X86::RET32:
3911 case X86::RET64:
3912 case X86::RETI16:
3913 case X86::RETI32:
3914 case X86::RETI64: {
3915 MCInst ShlInst, FenceInst;
3916 bool Parse32 = is32BitMode() || Code16GCC;
3917 unsigned Basereg =
3918 is64BitMode() ? X86::RSP : (Parse32 ? X86::ESP : X86::SP);
3919 const MCExpr *Disp = MCConstantExpr::create(0, getContext());
3920 auto ShlMemOp = X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
3921 /*BaseReg=*/Basereg, /*IndexReg=*/0,
3922 /*Scale=*/1, SMLoc{}, SMLoc{}, 0);
3923 ShlInst.setOpcode(X86::SHL64mi);
3924 ShlMemOp->addMemOperands(ShlInst, 5);
3925 ShlInst.addOperand(MCOperand::createImm(0));
3926 FenceInst.setOpcode(X86::LFENCE);
3927 Out.emitInstruction(ShlInst, getSTI());
3928 Out.emitInstruction(FenceInst, getSTI());
3929 return;
3930 }
3931 case X86::JMP16m:
3932 case X86::JMP32m:
3933 case X86::JMP64m:
3934 case X86::CALL16m:
3935 case X86::CALL32m:
3936 case X86::CALL64m:
3937 emitWarningForSpecialLVIInstruction(Inst.getLoc());
3938 return;
3939 }
3940}
3941
3942/// To mitigate LVI, every instruction that performs a load can be followed by
3943/// an LFENCE instruction to squash any potential mis-speculation. There are
3944/// some instructions that require additional considerations, and may requre
3945/// manual mitigation. For more details, see:
3946/// https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection
3947///
3948/// Returns `true` if a mitigation was applied or warning was emitted.
3949void X86AsmParser::applyLVILoadHardeningMitigation(MCInst &Inst,
3950 MCStreamer &Out) {
3951 auto Opcode = Inst.getOpcode();
3952 auto Flags = Inst.getFlags();
3953 if ((Flags & X86::IP_HAS_REPEAT) || (Flags & X86::IP_HAS_REPEAT_NE)) {
3954 // Information on REP string instructions that require manual mitigation can
3955 // be found here:
3956 // https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection#specialinstructions
3957 switch (Opcode) {
3958 case X86::CMPSB:
3959 case X86::CMPSW:
3960 case X86::CMPSL:
3961 case X86::CMPSQ:
3962 case X86::SCASB:
3963 case X86::SCASW:
3964 case X86::SCASL:
3965 case X86::SCASQ:
3966 emitWarningForSpecialLVIInstruction(Inst.getLoc());
3967 return;
3968 }
3969 } else if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) {
3970 // If a REP instruction is found on its own line, it may or may not be
3971 // followed by a vulnerable instruction. Emit a warning just in case.
3972 emitWarningForSpecialLVIInstruction(Inst.getLoc());
3973 return;
3974 }
3975
3976 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
3977
3978 // Can't mitigate after terminators or calls. A control flow change may have
3979 // already occurred.
3980 if (MCID.isTerminator() || MCID.isCall())
3981 return;
3982
3983 // LFENCE has the mayLoad property, don't double fence.
3984 if (MCID.mayLoad() && Inst.getOpcode() != X86::LFENCE) {
3986 FenceInst.setOpcode(X86::LFENCE);
3987 Out.emitInstruction(FenceInst, getSTI());
3988 }
3989}
3990
3991void X86AsmParser::emitInstruction(MCInst &Inst, OperandVector &Operands,
3992 MCStreamer &Out) {
3994 getSTI().hasFeature(X86::FeatureLVIControlFlowIntegrity))
3995 applyLVICFIMitigation(Inst, Out);
3996
3997 Out.emitInstruction(Inst, getSTI());
3998
4000 getSTI().hasFeature(X86::FeatureLVILoadHardening))
4001 applyLVILoadHardeningMitigation(Inst, Out);
4002}
4003
4004bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
4007 bool MatchingInlineAsm) {
4008 if (isParsingIntelSyntax())
4009 return MatchAndEmitIntelInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
4010 MatchingInlineAsm);
4011 return MatchAndEmitATTInstruction(IDLoc, Opcode, Operands, Out, ErrorInfo,
4012 MatchingInlineAsm);
4013}
4014
4015void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
4017 bool MatchingInlineAsm) {
4018 // FIXME: This should be replaced with a real .td file alias mechanism.
4019 // Also, MatchInstructionImpl should actually *do* the EmitInstruction
4020 // call.
4021 const char *Repl = StringSwitch<const char *>(Op.getToken())
4022 .Case("finit", "fninit")
4023 .Case("fsave", "fnsave")
4024 .Case("fstcw", "fnstcw")
4025 .Case("fstcww", "fnstcw")
4026 .Case("fstenv", "fnstenv")
4027 .Case("fstsw", "fnstsw")
4028 .Case("fstsww", "fnstsw")
4029 .Case("fclex", "fnclex")
4030 .Default(nullptr);
4031 if (Repl) {
4032 MCInst Inst;
4033 Inst.setOpcode(X86::WAIT);
4034 Inst.setLoc(IDLoc);
4035 if (!MatchingInlineAsm)
4036 emitInstruction(Inst, Operands, Out);
4037 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
4038 }
4039}
4040
4041bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc,
4042 const FeatureBitset &MissingFeatures,
4043 bool MatchingInlineAsm) {
4044 assert(MissingFeatures.any() && "Unknown missing feature!");
4047 OS << "instruction requires:";
4048 for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {
4049 if (MissingFeatures[i])
4050 OS << ' ' << getSubtargetFeatureName(i);
4051 }
4052 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
4053}
4054
4056 unsigned Result = 0;
4057 X86Operand &Prefix = static_cast<X86Operand &>(*Operands.back());
4058 if (Prefix.isPrefix()) {
4059 Result = Prefix.getPrefix();
4060 Operands.pop_back();
4061 }
4062 return Result;
4063}
4064
4065unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {
4066 unsigned Opc = Inst.getOpcode();
4067 const MCInstrDesc &MCID = MII.get(Opc);
4068
4069 if (UseApxExtendedReg && !X86II::canUseApxExtendedReg(MCID))
4070 return Match_Unsupported;
4071 if (ForcedNoFlag == !(MCID.TSFlags & X86II::EVEX_NF) && !X86::isCFCMOVCC(Opc))
4072 return Match_Unsupported;
4073
4074 if (ForcedVEXEncoding == VEXEncoding_EVEX &&
4076 return Match_Unsupported;
4077
4078 if ((ForcedVEXEncoding == VEXEncoding_VEX ||
4079 ForcedVEXEncoding == VEXEncoding_VEX2 ||
4080 ForcedVEXEncoding == VEXEncoding_VEX3) &&
4082 return Match_Unsupported;
4083
4084 if ((MCID.TSFlags & X86II::ExplicitOpPrefixMask) ==
4086 (ForcedVEXEncoding != VEXEncoding_VEX &&
4087 ForcedVEXEncoding != VEXEncoding_VEX2 &&
4088 ForcedVEXEncoding != VEXEncoding_VEX3))
4089 return Match_Unsupported;
4090
4091 return Match_Success;
4092}
4093
4094bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
4096 MCStreamer &Out,
4098 bool MatchingInlineAsm) {
4099 assert(!Operands.empty() && "Unexpect empty operand list!");
4100 assert((*Operands[0]).isToken() && "Leading operand should always be a mnemonic!");
4101 SMRange EmptyRange = std::nullopt;
4102
4103 // First, handle aliases that expand to multiple instructions.
4104 MatchFPUWaitAlias(IDLoc, static_cast<X86Operand &>(*Operands[0]), Operands,
4105 Out, MatchingInlineAsm);
4106 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
4107 unsigned Prefixes = getPrefixes(Operands);
4108
4109 MCInst Inst;
4110
4111 // If VEX/EVEX encoding is forced, we need to pass the USE_* flag to the
4112 // encoder and printer.
4113 if (ForcedVEXEncoding == VEXEncoding_VEX)
4114 Prefixes |= X86::IP_USE_VEX;
4115 else if (ForcedVEXEncoding == VEXEncoding_VEX2)
4116 Prefixes |= X86::IP_USE_VEX2;
4117 else if (ForcedVEXEncoding == VEXEncoding_VEX3)
4118 Prefixes |= X86::IP_USE_VEX3;
4119 else if (ForcedVEXEncoding == VEXEncoding_EVEX)
4120 Prefixes |= X86::IP_USE_EVEX;
4121
4122 // Set encoded flags for {disp8} and {disp32}.
4123 if (ForcedDispEncoding == DispEncoding_Disp8)
4124 Prefixes |= X86::IP_USE_DISP8;
4125 else if (ForcedDispEncoding == DispEncoding_Disp32)
4126 Prefixes |= X86::IP_USE_DISP32;
4127
4128 if (Prefixes)
4129 Inst.setFlags(Prefixes);
4130
4131 // In 16-bit mode, if data32 is specified, temporarily switch to 32-bit mode
4132 // when matching the instruction.
4133 if (ForcedDataPrefix == X86::Is32Bit)
4134 SwitchMode(X86::Is32Bit);
4135 // First, try a direct match.
4136 FeatureBitset MissingFeatures;
4137 unsigned OriginalError = MatchInstruction(Operands, Inst, ErrorInfo,
4138 MissingFeatures, MatchingInlineAsm,
4139 isParsingIntelSyntax());
4140 if (ForcedDataPrefix == X86::Is32Bit) {
4141 SwitchMode(X86::Is16Bit);
4142 ForcedDataPrefix = 0;
4143 }
4144 switch (OriginalError) {
4145 default: llvm_unreachable("Unexpected match result!");
4146 case Match_Success:
4147 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4148 return true;
4149 // Some instructions need post-processing to, for example, tweak which
4150 // encoding is selected. Loop on it while changes happen so the
4151 // individual transformations can chain off each other.
4152 if (!MatchingInlineAsm)
4153 while (processInstruction(Inst, Operands))
4154 ;
4155
4156 Inst.setLoc(IDLoc);
4157 if (!MatchingInlineAsm)
4158 emitInstruction(Inst, Operands, Out);
4159 Opcode = Inst.getOpcode();
4160 return false;
4161 case Match_InvalidImmUnsignedi4: {
4162 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4163 if (ErrorLoc == SMLoc())
4164 ErrorLoc = IDLoc;
4165 return Error(ErrorLoc, "immediate must be an integer in range [0, 15]",
4166 EmptyRange, MatchingInlineAsm);
4167 }
4168 case Match_MissingFeature:
4169 return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);
4170 case Match_InvalidOperand:
4171 case Match_MnemonicFail:
4172 case Match_Unsupported:
4173 break;
4174 }
4175 if (Op.getToken().empty()) {
4176 Error(IDLoc, "instruction must have size higher than 0", EmptyRange,
4177 MatchingInlineAsm);
4178 return true;
4179 }
4180
4181 // FIXME: Ideally, we would only attempt suffix matches for things which are
4182 // valid prefixes, and we could just infer the right unambiguous
4183 // type. However, that requires substantially more matcher support than the
4184 // following hack.
4185
4186 // Change the operand to point to a temporary token.
4187 StringRef Base = Op.getToken();
4188 SmallString<16> Tmp;
4189 Tmp += Base;
4190 Tmp += ' ';
4191 Op.setTokenValue(Tmp);
4192
4193 // If this instruction starts with an 'f', then it is a floating point stack
4194 // instruction. These come in up to three forms for 32-bit, 64-bit, and
4195 // 80-bit floating point, which use the suffixes s,l,t respectively.
4196 //
4197 // Otherwise, we assume that this may be an integer instruction, which comes
4198 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
4199 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
4200 // MemSize corresponding to Suffixes. { 8, 16, 32, 64 } { 32, 64, 80, 0 }
4201 const char *MemSize = Base[0] != 'f' ? "\x08\x10\x20\x40" : "\x20\x40\x50\0";
4202
4203 // Check for the various suffix matches.
4204 uint64_t ErrorInfoIgnore;
4205 FeatureBitset ErrorInfoMissingFeatures; // Init suppresses compiler warnings.
4206 unsigned Match[4];
4207
4208 // Some instruction like VPMULDQ is NOT the variant of VPMULD but a new one.
4209 // So we should make sure the suffix matcher only works for memory variant
4210 // that has the same size with the suffix.
4211 // FIXME: This flag is a workaround for legacy instructions that didn't
4212 // declare non suffix variant assembly.
4213 bool HasVectorReg = false;
4214 X86Operand *MemOp = nullptr;
4215 for (const auto &Op : Operands) {
4216 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
4217 if (X86Op->isVectorReg())
4218 HasVectorReg = true;
4219 else if (X86Op->isMem()) {
4220 MemOp = X86Op;
4221 assert(MemOp->Mem.Size == 0 && "Memory size always 0 under ATT syntax");
4222 // Have we found an unqualified memory operand,
4223 // break. IA allows only one memory operand.
4224 break;
4225 }
4226 }
4227
4228 for (unsigned I = 0, E = std::size(Match); I != E; ++I) {
4229 Tmp.back() = Suffixes[I];
4230 if (MemOp && HasVectorReg)
4231 MemOp->Mem.Size = MemSize[I];
4232 Match[I] = Match_MnemonicFail;
4233 if (MemOp || !HasVectorReg) {
4234 Match[I] =
4235 MatchInstruction(Operands, Inst, ErrorInfoIgnore, MissingFeatures,
4236 MatchingInlineAsm, isParsingIntelSyntax());
4237 // If this returned as a missing feature failure, remember that.
4238 if (Match[I] == Match_MissingFeature)
4239 ErrorInfoMissingFeatures = MissingFeatures;
4240 }
4241 }
4242
4243 // Restore the old token.
4244 Op.setTokenValue(Base);
4245
4246 // If exactly one matched, then we treat that as a successful match (and the
4247 // instruction will already have been filled in correctly, since the failing
4248 // matches won't have modified it).
4249 unsigned NumSuccessfulMatches = llvm::count(Match, Match_Success);
4250 if (NumSuccessfulMatches == 1) {
4251 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4252 return true;
4253 // Some instructions need post-processing to, for example, tweak which
4254 // encoding is selected. Loop on it while changes happen so the
4255 // individual transformations can chain off each other.
4256 if (!MatchingInlineAsm)
4257 while (processInstruction(Inst, Operands))
4258 ;
4259
4260 Inst.setLoc(IDLoc);
4261 if (!MatchingInlineAsm)
4262 emitInstruction(Inst, Operands, Out);
4263 Opcode = Inst.getOpcode();
4264 return false;
4265 }
4266
4267 // Otherwise, the match failed, try to produce a decent error message.
4268
4269 // If we had multiple suffix matches, then identify this as an ambiguous
4270 // match.
4271 if (NumSuccessfulMatches > 1) {
4272 char MatchChars[4];
4273 unsigned NumMatches = 0;
4274 for (unsigned I = 0, E = std::size(Match); I != E; ++I)
4275 if (Match[I] == Match_Success)
4276 MatchChars[NumMatches++] = Suffixes[I];
4277
4280 OS << "ambiguous instructions require an explicit suffix (could be ";
4281 for (unsigned i = 0; i != NumMatches; ++i) {
4282 if (i != 0)
4283 OS << ", ";
4284 if (i + 1 == NumMatches)
4285 OS << "or ";
4286 OS << "'" << Base << MatchChars[i] << "'";
4287 }
4288 OS << ")";
4289 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
4290 return true;
4291 }
4292
4293 // Okay, we know that none of the variants matched successfully.
4294
4295 // If all of the instructions reported an invalid mnemonic, then the original
4296 // mnemonic was invalid.
4297 if (llvm::count(Match, Match_MnemonicFail) == 4) {
4298 if (OriginalError == Match_MnemonicFail)
4299 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
4300 Op.getLocRange(), MatchingInlineAsm);
4301
4302 if (OriginalError == Match_Unsupported)
4303 return Error(IDLoc, "unsupported instruction", EmptyRange,
4304 MatchingInlineAsm);
4305
4306 assert(OriginalError == Match_InvalidOperand && "Unexpected error");
4307 // Recover location info for the operand if we know which was the problem.
4308 if (ErrorInfo != ~0ULL) {
4309 if (ErrorInfo >= Operands.size())
4310 return Error(IDLoc, "too few operands for instruction", EmptyRange,
4311 MatchingInlineAsm);
4312
4313 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
4314 if (Operand.getStartLoc().isValid()) {
4315 SMRange OperandRange = Operand.getLocRange();
4316 return Error(Operand.getStartLoc(), "invalid operand for instruction",
4317 OperandRange, MatchingInlineAsm);
4318 }
4319 }
4320
4321 return Error(IDLoc, "invalid operand for instruction", EmptyRange,
4322 MatchingInlineAsm);
4323 }
4324
4325 // If one instruction matched as unsupported, report this as unsupported.
4326 if (llvm::count(Match, Match_Unsupported) == 1) {
4327 return Error(IDLoc, "unsupported instruction", EmptyRange,
4328 MatchingInlineAsm);
4329 }
4330
4331 // If one instruction matched with a missing feature, report this as a
4332 // missing feature.
4333 if (llvm::count(Match, Match_MissingFeature) == 1) {
4334 ErrorInfo = Match_MissingFeature;
4335 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4336 MatchingInlineAsm);
4337 }
4338
4339 // If one instruction matched with an invalid operand, report this as an
4340 // operand failure.
4341 if (llvm::count(Match, Match_InvalidOperand) == 1) {
4342 return Error(IDLoc, "invalid operand for instruction", EmptyRange,
4343 MatchingInlineAsm);
4344 }
4345
4346 // If all of these were an outright failure, report it in a useless way.
4347 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
4348 EmptyRange, MatchingInlineAsm);
4349 return true;
4350}
4351
4352bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
4354 MCStreamer &Out,
4356 bool MatchingInlineAsm) {
4357 assert(!Operands.empty() && "Unexpect empty operand list!");
4358 assert((*Operands[0]).isToken() && "Leading operand should always be a mnemonic!");
4359 StringRef Mnemonic = (static_cast<X86Operand &>(*Operands[0])).getToken();
4360 SMRange EmptyRange = std::nullopt;
4361 StringRef Base = (static_cast<X86Operand &>(*Operands[0])).getToken();
4362 unsigned Prefixes = getPrefixes(Operands);
4363
4364 // First, handle aliases that expand to multiple instructions.
4365 MatchFPUWaitAlias(IDLoc, static_cast<X86Operand &>(*Operands[0]), Operands, Out, MatchingInlineAsm);
4366 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
4367
4368 MCInst Inst;
4369
4370 // If VEX/EVEX encoding is forced, we need to pass the USE_* flag to the
4371 // encoder and printer.
4372 if (ForcedVEXEncoding == VEXEncoding_VEX)
4373 Prefixes |= X86::IP_USE_VEX;
4374 else if (ForcedVEXEncoding == VEXEncoding_VEX2)
4375 Prefixes |= X86::IP_USE_VEX2;
4376 else if (ForcedVEXEncoding == VEXEncoding_VEX3)
4377 Prefixes |= X86::IP_USE_VEX3;
4378 else if (ForcedVEXEncoding == VEXEncoding_EVEX)
4379 Prefixes |= X86::IP_USE_EVEX;
4380
4381 // Set encoded flags for {disp8} and {disp32}.
4382 if (ForcedDispEncoding == DispEncoding_Disp8)
4383 Prefixes |= X86::IP_USE_DISP8;
4384 else if (ForcedDispEncoding == DispEncoding_Disp32)
4385 Prefixes |= X86::IP_USE_DISP32;
4386
4387 if (Prefixes)
4388 Inst.setFlags(Prefixes);
4389
4390 // Find one unsized memory operand, if present.
4391 X86Operand *UnsizedMemOp = nullptr;
4392 for (const auto &Op : Operands) {
4393 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
4394 if (X86Op->isMemUnsized()) {
4395 UnsizedMemOp = X86Op;
4396 // Have we found an unqualified memory operand,
4397 // break. IA allows only one memory operand.
4398 break;
4399 }
4400 }
4401
4402 // Allow some instructions to have implicitly pointer-sized operands. This is
4403 // compatible with gas.
4404 if (UnsizedMemOp) {
4405 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
4406 for (const char *Instr : PtrSizedInstrs) {
4407 if (Mnemonic == Instr) {
4408 UnsizedMemOp->Mem.Size = getPointerWidth();
4409 break;
4410 }
4411 }
4412 }
4413
4415 FeatureBitset ErrorInfoMissingFeatures;
4416 FeatureBitset MissingFeatures;
4417
4418 // If unsized push has immediate operand we should default the default pointer
4419 // size for the size.
4420 if (Mnemonic == "push" && Operands.size() == 2) {
4421 auto *X86Op = static_cast<X86Operand *>(Operands[1].get());
4422 if (X86Op->isImm()) {
4423 // If it's not a constant fall through and let remainder take care of it.
4424 const auto *CE = dyn_cast<MCConstantExpr>(X86Op->getImm());
4425 unsigned Size = getPointerWidth();
4426 if (CE &&
4427 (isIntN(Size, CE->getValue()) || isUIntN(Size, CE->getValue()))) {
4428 SmallString<16> Tmp;
4429 Tmp += Base;
4430 Tmp += (is64BitMode())
4431 ? "q"
4432 : (is32BitMode()) ? "l" : (is16BitMode()) ? "w" : " ";
4433 Op.setTokenValue(Tmp);
4434 // Do match in ATT mode to allow explicit suffix usage.
4435 Match.push_back(MatchInstruction(Operands, Inst, ErrorInfo,
4436 MissingFeatures, MatchingInlineAsm,
4437 false /*isParsingIntelSyntax()*/));
4438 Op.setTokenValue(Base);
4439 }
4440 }
4441 }
4442
4443 // If an unsized memory operand is present, try to match with each memory
4444 // operand size. In Intel assembly, the size is not part of the instruction
4445 // mnemonic.
4446 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
4447 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
4448 for (unsigned Size : MopSizes) {
4449 UnsizedMemOp->Mem.Size = Size;
4450 uint64_t ErrorInfoIgnore;
4451 unsigned LastOpcode = Inst.getOpcode();
4452 unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
4453 MissingFeatures, MatchingInlineAsm,
4454 isParsingIntelSyntax());
4455 if (Match.empty() || LastOpcode != Inst.getOpcode())
4456 Match.push_back(M);
4457
4458 // If this returned as a missing feature failure, remember that.
4459 if (Match.back() == Match_MissingFeature)
4460 ErrorInfoMissingFeatures = MissingFeatures;
4461 }
4462
4463 // Restore the size of the unsized memory operand if we modified it.
4464 UnsizedMemOp->Mem.Size = 0;
4465 }
4466
4467 // If we haven't matched anything yet, this is not a basic integer or FPU
4468 // operation. There shouldn't be any ambiguity in our mnemonic table, so try
4469 // matching with the unsized operand.
4470 if (Match.empty()) {
4471 Match.push_back(MatchInstruction(
4472 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4473 isParsingIntelSyntax()));
4474 // If this returned as a missing feature failure, remember that.
4475 if (Match.back() == Match_MissingFeature)
4476 ErrorInfoMissingFeatures = MissingFeatures;
4477 }
4478
4479 // Restore the size of the unsized memory operand if we modified it.
4480 if (UnsizedMemOp)
4481 UnsizedMemOp->Mem.Size = 0;
4482
4483 // If it's a bad mnemonic, all results will be the same.
4484 if (Match.back() == Match_MnemonicFail) {
4485 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
4486 Op.getLocRange(), MatchingInlineAsm);
4487 }
4488
4489 unsigned NumSuccessfulMatches = llvm::count(Match, Match_Success);
4490
4491 // If matching was ambiguous and we had size information from the frontend,
4492 // try again with that. This handles cases like "movxz eax, m8/m16".
4493 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
4494 UnsizedMemOp->getMemFrontendSize()) {
4495 UnsizedMemOp->Mem.Size = UnsizedMemOp->getMemFrontendSize();
4496 unsigned M = MatchInstruction(
4497 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4498 isParsingIntelSyntax());
4499 if (M == Match_Success)
4500 NumSuccessfulMatches = 1;
4501
4502 // Add a rewrite that encodes the size information we used from the
4503 // frontend.
4504 InstInfo->AsmRewrites->emplace_back(
4505 AOK_SizeDirective, UnsizedMemOp->getStartLoc(),
4506 /*Len=*/0, UnsizedMemOp->getMemFrontendSize());
4507 }
4508
4509 // If exactly one matched, then we treat that as a successful match (and the
4510 // instruction will already have been filled in correctly, since the failing
4511 // matches won't have modified it).
4512 if (NumSuccessfulMatches == 1) {
4513 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4514 return true;
4515 // Some instructions need post-processing to, for example, tweak which
4516 // encoding is selected. Loop on it while changes happen so the individual
4517 // transformations can chain off each other.
4518 if (!MatchingInlineAsm)
4519 while (processInstruction(Inst, Operands))
4520 ;
4521 Inst.setLoc(IDLoc);
4522 if (!MatchingInlineAsm)
4523 emitInstruction(Inst, Operands, Out);
4524 Opcode = Inst.getOpcode();
4525 return false;
4526 } else if (NumSuccessfulMatches > 1) {
4527 assert(UnsizedMemOp &&
4528 "multiple matches only possible with unsized memory operands");
4529 return Error(UnsizedMemOp->getStartLoc(),
4530 "ambiguous operand size for instruction '" + Mnemonic + "\'",
4531 UnsizedMemOp->getLocRange());
4532 }
4533
4534 // If one instruction matched as unsupported, report this as unsupported.
4535 if (llvm::count(Match, Match_Unsupported) == 1) {
4536 return Error(IDLoc, "unsupported instruction", EmptyRange,
4537 MatchingInlineAsm);
4538 }
4539
4540 // If one instruction matched with a missing feature, report this as a
4541 // missing feature.
4542 if (llvm::count(Match, Match_MissingFeature) == 1) {
4543 ErrorInfo = Match_MissingFeature;
4544 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4545 MatchingInlineAsm);
4546 }
4547
4548 // If one instruction matched with an invalid operand, report this as an
4549 // operand failure.
4550 if (llvm::count(Match, Match_InvalidOperand) == 1) {
4551 return Error(IDLoc, "invalid operand for instruction", EmptyRange,
4552 MatchingInlineAsm);
4553 }
4554
4555 if (llvm::count(Match, Match_InvalidImmUnsignedi4) == 1) {
4556 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4557 if (ErrorLoc == SMLoc())
4558 ErrorLoc = IDLoc;
4559 return Error(ErrorLoc, "immediate must be an integer in range [0, 15]",
4560 EmptyRange, MatchingInlineAsm);
4561 }
4562
4563 // If all of these were an outright failure, report it in a useless way.
4564 return Error(IDLoc, "unknown instruction mnemonic", EmptyRange,
4565 MatchingInlineAsm);
4566}
4567
4568bool X86AsmParser::OmitRegisterFromClobberLists(unsigned RegNo) {
4569 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo);
4570}
4571
4572bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
4573 MCAsmParser &Parser = getParser();
4574 StringRef IDVal = DirectiveID.getIdentifier();
4575 if (IDVal.starts_with(".arch"))
4576 return parseDirectiveArch();
4577 if (IDVal.starts_with(".code"))
4578 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
4579 else if (IDVal.starts_with(".att_syntax")) {
4580 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4581 if (Parser.getTok().getString() == "prefix")
4582 Parser.Lex();
4583 else if (Parser.getTok().getString() == "noprefix")
4584 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
4585 "supported: registers must have a "
4586 "'%' prefix in .att_syntax");
4587 }
4588 getParser().setAssemblerDialect(0);
4589 return false;
4590 } else if (IDVal.starts_with(".intel_syntax")) {
4591 getParser().setAssemblerDialect(1);
4592 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4593 if (Parser.getTok().getString() == "noprefix")
4594 Parser.Lex();
4595 else if (Parser.getTok().getString() == "prefix")
4596 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
4597 "supported: registers must not have "
4598 "a '%' prefix in .intel_syntax");
4599 }
4600 return false;
4601 } else if (IDVal == ".nops")
4602 return parseDirectiveNops(DirectiveID.getLoc());
4603 else if (IDVal == ".even")
4604 return parseDirectiveEven(DirectiveID.getLoc());
4605 else if (IDVal == ".cv_fpo_proc")
4606 return parseDirectiveFPOProc(DirectiveID.getLoc());
4607 else if (IDVal == ".cv_fpo_setframe")
4608 return parseDirectiveFPOSetFrame(DirectiveID.getLoc());
4609 else if (IDVal == ".cv_fpo_pushreg")
4610 return parseDirectiveFPOPushReg(DirectiveID.getLoc());
4611 else if (IDVal == ".cv_fpo_stackalloc")
4612 return parseDirectiveFPOStackAlloc(DirectiveID.getLoc());
4613 else if (IDVal == ".cv_fpo_stackalign")
4614 return parseDirectiveFPOStackAlign(DirectiveID.getLoc());
4615 else if (IDVal == ".cv_fpo_endprologue")
4616 return parseDirectiveFPOEndPrologue(DirectiveID.getLoc());
4617 else if (IDVal == ".cv_fpo_endproc")
4618 return parseDirectiveFPOEndProc(DirectiveID.getLoc());
4619 else if (IDVal == ".seh_pushreg" ||
4620 (Parser.isParsingMasm() && IDVal.equals_insensitive(".pushreg")))
4621 return parseDirectiveSEHPushReg(DirectiveID.getLoc());
4622 else if (IDVal == ".seh_setframe" ||
4623 (Parser.isParsingMasm() && IDVal.equals_insensitive(".setframe")))
4624 return parseDirectiveSEHSetFrame(DirectiveID.getLoc());
4625 else if (IDVal == ".seh_savereg" ||
4626 (Parser.isParsingMasm() && IDVal.equals_insensitive(".savereg")))
4627 return parseDirectiveSEHSaveReg(DirectiveID.getLoc());
4628 else if (IDVal == ".seh_savexmm" ||
4629 (Parser.isParsingMasm() && IDVal.equals_insensitive(".savexmm128")))
4630 return parseDirectiveSEHSaveXMM(DirectiveID.getLoc());
4631 else if (IDVal == ".seh_pushframe" ||
4632 (Parser.isParsingMasm() && IDVal.equals_insensitive(".pushframe")))
4633 return parseDirectiveSEHPushFrame(DirectiveID.getLoc());
4634
4635 return true;
4636}
4637
4638bool X86AsmParser::parseDirectiveArch() {
4639 // Ignore .arch for now.
4640 getParser().parseStringToEndOfStatement();
4641 return false;
4642}
4643
4644/// parseDirectiveNops
4645/// ::= .nops size[, control]
4646bool X86AsmParser::parseDirectiveNops(SMLoc L) {
4647 int64_t NumBytes = 0, Control = 0;
4648 SMLoc NumBytesLoc, ControlLoc;
4649 const MCSubtargetInfo& STI = getSTI();
4650 NumBytesLoc = getTok().getLoc();
4651 if (getParser().checkForValidSection() ||
4652 getParser().parseAbsoluteExpression(NumBytes))
4653 return true;
4654
4655 if (parseOptionalToken(AsmToken::Comma)) {
4656 ControlLoc = getTok().getLoc();
4657 if (getParser().parseAbsoluteExpression(Control))
4658 return true;
4659 }
4660 if (getParser().parseEOL())
4661 return true;
4662
4663 if (NumBytes <= 0) {
4664 Error(NumBytesLoc, "'.nops' directive with non-positive size");
4665 return false;
4666 }
4667
4668 if (Control < 0) {
4669 Error(ControlLoc, "'.nops' directive with negative NOP size");
4670 return false;
4671 }
4672
4673 /// Emit nops
4674 getParser().getStreamer().emitNops(NumBytes, Control, L, STI);
4675
4676 return false;
4677}
4678
4679/// parseDirectiveEven
4680/// ::= .even
4681bool X86AsmParser::parseDirectiveEven(SMLoc L) {
4682 if (parseEOL())
4683 return false;
4684
4685 const MCSection *Section = getStreamer().getCurrentSectionOnly();
4686 if (!Section) {
4687 getStreamer().initSections(false, getSTI());
4688 Section = getStreamer().getCurrentSectionOnly();
4689 }
4690 if (Section->useCodeAlign())
4691 getStreamer().emitCodeAlignment(Align(2), &getSTI(), 0);
4692 else
4693 getStreamer().emitValueToAlignment(Align(2), 0, 1, 0);
4694 return false;
4695}
4696
4697/// ParseDirectiveCode
4698/// ::= .code16 | .code32 | .code64
4699bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
4700 MCAsmParser &Parser = getParser();
4701 Code16GCC = false;
4702 if (IDVal == ".code16") {
4703 Parser.Lex();
4704 if (!is16BitMode()) {
4705 SwitchMode(X86::Is16Bit);
4706 getParser().getStreamer().emitAssemblerFlag(MCAF_Code16);
4707 }
4708 } else if (IDVal == ".code16gcc") {
4709 // .code16gcc parses as if in 32-bit mode, but emits code in 16-bit mode.
4710 Parser.Lex();
4711 Code16GCC = true;
4712 if (!is16BitMode()) {
4713 SwitchMode(X86::Is16Bit);
4714 getParser().getStreamer().emitAssemblerFlag(MCAF_Code16);
4715 }
4716 } else if (IDVal == ".code32") {
4717 Parser.Lex();
4718 if (!is32BitMode()) {
4719 SwitchMode(X86::Is32Bit);
4720 getParser().getStreamer().emitAssemblerFlag(MCAF_Code32);
4721 }
4722 } else if (IDVal == ".code64") {
4723 Parser.Lex();
4724 if (!is64BitMode()) {
4725 SwitchMode(X86::Is64Bit);
4726 getParser().getStreamer().emitAssemblerFlag(MCAF_Code64);
4727 }
4728 } else {
4729 Error(L, "unknown directive " + IDVal);
4730 return false;
4731 }
4732
4733 return false;
4734}
4735
4736// .cv_fpo_proc foo
4737bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {
4738 MCAsmParser &Parser = getParser();
4739 StringRef ProcName;
4740 int64_t ParamsSize;
4741 if (Parser.parseIdentifier(ProcName))
4742 return Parser.TokError("expected symbol name");
4743 if (Parser.parseIntToken(ParamsSize, "expected parameter byte count"))
4744 return true;
4745 if (!isUIntN(32, ParamsSize))
4746 return Parser.TokError("parameters size out of range");
4747 if (parseEOL())
4748 return true;
4749 MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
4750 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
4751}
4752
4753// .cv_fpo_setframe ebp
4754bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {
4756 SMLoc DummyLoc;
4757 if (parseRegister(Reg, DummyLoc, DummyLoc) || parseEOL())
4758 return true;
4759 return getTargetStreamer().emitFPOSetFrame(Reg, L);
4760}
4761
4762// .cv_fpo_pushreg ebx
4763bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {
4765 SMLoc DummyLoc;
4766 if (parseRegister(Reg, DummyLoc, DummyLoc) || parseEOL())
4767 return true;
4768 return getTargetStreamer().emitFPOPushReg(Reg, L);
4769}
4770
4771// .cv_fpo_stackalloc 20
4772bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {
4773 MCAsmParser &Parser = getParser();
4774 int64_t Offset;
4775 if (Parser.parseIntToken(Offset, "expected offset") || parseEOL())
4776 return true;
4777 return getTargetStreamer().emitFPOStackAlloc(Offset, L);
4778}
4779
4780// .cv_fpo_stackalign 8
4781bool X86AsmParser::parseDirectiveFPOStackAlign(SMLoc L) {
4782 MCAsmParser &Parser = getParser();
4783 int64_t Offset;
4784 if (Parser.parseIntToken(Offset, "expected offset") || parseEOL())
4785 return true;
4786 return getTargetStreamer().emitFPOStackAlign(Offset, L);
4787}
4788
4789// .cv_fpo_endprologue
4790bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {
4791 MCAsmParser &Parser = getParser();
4792 if (Parser.parseEOL())
4793 return true;
4794 return getTargetStreamer().emitFPOEndPrologue(L);
4795}
4796
4797// .cv_fpo_endproc
4798bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {
4799 MCAsmParser &Parser = getParser();
4800 if (Parser.parseEOL())
4801 return true;
4802 return getTargetStreamer().emitFPOEndProc(L);
4803}
4804
4805bool X86AsmParser::parseSEHRegisterNumber(unsigned RegClassID,
4806 MCRegister &RegNo) {
4807 SMLoc startLoc = getLexer().getLoc();
4808 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
4809
4810 // Try parsing the argument as a register first.
4811 if (getLexer().getTok().isNot(AsmToken::Integer)) {
4812 SMLoc endLoc;
4813 if (parseRegister(RegNo, startLoc, endLoc))
4814 return true;
4815
4816 if (!X86MCRegisterClasses[RegClassID].contains(RegNo)) {
4817 return Error(startLoc,
4818 "register is not supported for use with this directive");
4819 }
4820 } else {
4821 // Otherwise, an integer number matching the encoding of the desired
4822 // register may appear.
4823 int64_t EncodedReg;
4824 if (getParser().parseAbsoluteExpression(EncodedReg))
4825 return true;
4826
4827 // The SEH register number is the same as the encoding register number. Map
4828 // from the encoding back to the LLVM register number.
4829 RegNo = 0;
4830 for (MCPhysReg Reg : X86MCRegisterClasses[RegClassID]) {
4831 if (MRI->getEncodingValue(Reg) == EncodedReg) {
4832 RegNo = Reg;
4833 break;
4834 }
4835 }
4836 if (RegNo == 0) {
4837 return Error(startLoc,
4838 "incorrect register number for use with this directive");
4839 }
4840 }
4841
4842 return false;
4843}
4844
4845bool X86AsmParser::parseDirectiveSEHPushReg(SMLoc Loc) {
4847 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg))
4848 return true;
4849
4850 if (getLexer().isNot(AsmToken::EndOfStatement))
4851 return TokError("expected end of directive");
4852
4853 getParser().Lex();
4854 getStreamer().emitWinCFIPushReg(Reg, Loc);
4855 return false;
4856}
4857
4858bool X86AsmParser::parseDirectiveSEHSetFrame(SMLoc Loc) {
4860 int64_t Off;
4861 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg))
4862 return true;
4863 if (getLexer().isNot(AsmToken::Comma))
4864 return TokError("you must specify a stack pointer offset");
4865
4866 getParser().Lex();
4867 if (getParser().parseAbsoluteExpression(Off))
4868 return true;
4869
4870 if (getLexer().isNot(AsmToken::EndOfStatement))
4871 return TokError("expected end of directive");
4872
4873 getParser().Lex();
4874 getStreamer().emitWinCFISetFrame(Reg, Off, Loc);
4875 return false;
4876}
4877
4878bool X86AsmParser::parseDirectiveSEHSaveReg(SMLoc Loc) {
4880 int64_t Off;
4881 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg))
4882 return true;
4883 if (getLexer().isNot(AsmToken::Comma))
4884 return TokError("you must specify an offset on the stack");
4885
4886 getParser().Lex();
4887 if (getParser().parseAbsoluteExpression(Off))
4888 return true;
4889
4890 if (getLexer().isNot(AsmToken::EndOfStatement))
4891 return TokError("expected end of directive");
4892
4893 getParser().Lex();
4894 getStreamer().emitWinCFISaveReg(Reg, Off, Loc);
4895 return false;
4896}
4897
4898bool X86AsmParser::parseDirectiveSEHSaveXMM(SMLoc Loc) {
4900 int64_t Off;
4901 if (parseSEHRegisterNumber(X86::VR128XRegClassID, Reg))
4902 return true;
4903 if (getLexer().isNot(AsmToken::Comma))
4904 return TokError("you must specify an offset on the stack");
4905
4906 getParser().Lex();
4907 if (getParser().parseAbsoluteExpression(Off))
4908 return true;
4909
4910 if (getLexer().isNot(AsmToken::EndOfStatement))
4911 return TokError("expected end of directive");
4912
4913 getParser().Lex();
4914 getStreamer().emitWinCFISaveXMM(Reg, Off, Loc);
4915 return false;
4916}
4917
4918bool X86AsmParser::parseDirectiveSEHPushFrame(SMLoc Loc) {
4919 bool Code = false;
4920 StringRef CodeID;
4921 if (getLexer().is(AsmToken::At)) {
4922 SMLoc startLoc = getLexer().getLoc();
4923 getParser().Lex();
4924 if (!getParser().parseIdentifier(CodeID)) {
4925 if (CodeID != "code")
4926 return Error(startLoc, "expected @code");
4927 Code = true;
4928 }
4929 }
4930
4931 if (getLexer().isNot(AsmToken::EndOfStatement))
4932 return TokError("expected end of directive");
4933
4934 getParser().Lex();
4935 getStreamer().emitWinCFIPushFrame(Code, Loc);
4936 return false;
4937}
4938
4939// Force static initialization.
4943}
4944
4945#define GET_MATCHER_IMPLEMENTATION
4946#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)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:135
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
std::string Name
uint64_t Size
bool End
Definition: ELF_riscv.cpp: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
@ 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
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
@ 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:1689
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:1923
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
unsigned getReg() const override
Definition: X86Operand.h:170
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
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