LLVM: lib/Target/X86/AsmParser/X86AsmParser.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
45#include
46#include
47#include
48
49using namespace llvm;
50
52 "x86-experimental-lvi-inline-asm-hardening",
53 cl::desc("Harden inline assembly code that may be vulnerable to Load Value"
54 " Injection (LVI). This feature is experimental."), cl::Hidden);
55
57 if (Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
58 ErrMsg = "scale factor in address must be 1, 2, 4 or 8";
59 return true;
60 }
61 return false;
62}
63
64namespace {
65
66
67#define GET_X86_SSE2AVX_TABLE
68#include "X86GenInstrMapping.inc"
69
70static const char OpPrecedence[] = {
71 0,
72 1,
73 2,
74 4,
75 4,
76 5,
77 5,
78 6,
79 6,
80 6,
81 7,
82 8,
83 9,
84 10,
85 0,
86 0,
87 3,
88 3,
89 3,
90 3,
91 3,
92 3
93};
94
96 ParseInstructionInfo *InstInfo;
97 bool Code16GCC;
98 unsigned ForcedDataPrefix = 0;
99
100 enum OpcodePrefix {
101 OpcodePrefix_Default,
102 OpcodePrefix_REX,
103 OpcodePrefix_REX2,
104 OpcodePrefix_VEX,
105 OpcodePrefix_VEX2,
106 OpcodePrefix_VEX3,
107 OpcodePrefix_EVEX,
108 };
109
110 OpcodePrefix ForcedOpcodePrefix = OpcodePrefix_Default;
111
112 enum DispEncoding {
113 DispEncoding_Default,
114 DispEncoding_Disp8,
115 DispEncoding_Disp32,
116 };
117
118 DispEncoding ForcedDispEncoding = DispEncoding_Default;
119
120
121 bool UseApxExtendedReg = false;
122
123 bool ForcedNoFlag = false;
124
125private:
126 SMLoc consumeToken() {
127 MCAsmParser &Parser = getParser();
129 Parser.Lex();
131 }
132
135 }
136
137 X86TargetStreamer &getTargetStreamer() {
138 assert(getParser().getStreamer().getTargetStreamer() &&
139 "do not have a target streamer");
140 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
141 return static_cast<X86TargetStreamer &>(TS);
142 }
143
144 unsigned MatchInstruction(const OperandVector &Operands, MCInst &Inst,
145 uint64_t &ErrorInfo, FeatureBitset &MissingFeatures,
146 bool matchingInlineAsm, unsigned VariantID = 0) {
147
148 if (Code16GCC)
149 SwitchMode(X86::Is32Bit);
150 unsigned rv = MatchInstructionImpl(Operands, Inst, ErrorInfo,
151 MissingFeatures, matchingInlineAsm,
152 VariantID);
153 if (Code16GCC)
154 SwitchMode(X86::Is16Bit);
155 return rv;
156 }
157
158 enum InfixCalculatorTok {
159 IC_OR = 0,
160 IC_XOR,
161 IC_AND,
162 IC_LSHIFT,
163 IC_RSHIFT,
164 IC_PLUS,
165 IC_MINUS,
166 IC_MULTIPLY,
167 IC_DIVIDE,
168 IC_MOD,
169 IC_NOT,
170 IC_NEG,
171 IC_RPAREN,
172 IC_LPAREN,
173 IC_IMM,
174 IC_REGISTER,
175 IC_EQ,
176 IC_NE,
177 IC_LT,
178 IC_LE,
179 IC_GT,
180 IC_GE
181 };
182
183 enum IntelOperatorKind {
184 IOK_INVALID = 0,
185 IOK_LENGTH,
186 IOK_SIZE,
187 IOK_TYPE,
188 };
189
190 enum MasmOperatorKind {
191 MOK_INVALID = 0,
192 MOK_LENGTHOF,
193 MOK_SIZEOF,
194 MOK_TYPE,
195 };
196
197 class InfixCalculator {
198 typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
201
202 bool isUnaryOperator(InfixCalculatorTok Op) const {
203 return Op == IC_NEG || Op == IC_NOT;
204 }
205
206 public:
207 int64_t popOperand() {
208 assert (!PostfixStack.empty() && "Poped an empty stack!");
209 ICToken Op = PostfixStack.pop_back_val();
210 if (!(Op.first == IC_IMM || Op.first == IC_REGISTER))
211 return -1;
212 return Op.second;
213 }
214 void pushOperand(InfixCalculatorTok Op, int64_t Val = 0) {
215 assert ((Op == IC_IMM || Op == IC_REGISTER) &&
216 "Unexpected operand!");
217 PostfixStack.push_back(std::make_pair(Op, Val));
218 }
219
220 void popOperator() { InfixOperatorStack.pop_back(); }
221 void pushOperator(InfixCalculatorTok Op) {
222
223 if (InfixOperatorStack.empty()) {
224 InfixOperatorStack.push_back(Op);
225 return;
226 }
227
228
229
230
231 unsigned Idx = InfixOperatorStack.size() - 1;
232 InfixCalculatorTok StackOp = InfixOperatorStack[Idx];
233 if (OpPrecedence[Op] > OpPrecedence[StackOp] || StackOp == IC_LPAREN) {
234 InfixOperatorStack.push_back(Op);
235 return;
236 }
237
238
239
240 unsigned ParenCount = 0;
241 while (true) {
242
243 if (InfixOperatorStack.empty())
244 break;
245
246 Idx = InfixOperatorStack.size() - 1;
247 StackOp = InfixOperatorStack[Idx];
248 if (!(OpPrecedence[StackOp] >= OpPrecedence[Op] || ParenCount))
249 break;
250
251
252
253 if (!ParenCount && StackOp == IC_LPAREN)
254 break;
255
256 if (StackOp == IC_RPAREN) {
257 ++ParenCount;
258 InfixOperatorStack.pop_back();
259 } else if (StackOp == IC_LPAREN) {
260 --ParenCount;
261 InfixOperatorStack.pop_back();
262 } else {
263 InfixOperatorStack.pop_back();
264 PostfixStack.push_back(std::make_pair(StackOp, 0));
265 }
266 }
267
268 InfixOperatorStack.push_back(Op);
269 }
270
271 int64_t execute() {
272
273 while (!InfixOperatorStack.empty()) {
274 InfixCalculatorTok StackOp = InfixOperatorStack.pop_back_val();
275 if (StackOp != IC_LPAREN && StackOp != IC_RPAREN)
276 PostfixStack.push_back(std::make_pair(StackOp, 0));
277 }
278
279 if (PostfixStack.empty())
280 return 0;
281
283 for (const ICToken &Op : PostfixStack) {
284 if (Op.first == IC_IMM || Op.first == IC_REGISTER) {
286 } else if (isUnaryOperator(Op.first)) {
287 assert (OperandStack.size() > 0 && "Too few operands.");
288 ICToken Operand = OperandStack.pop_back_val();
289 assert (Operand.first == IC_IMM &&
290 "Unary operation with a register!");
291 switch (Op.first) {
292 default:
294 break;
295 case IC_NEG:
296 OperandStack.push_back(std::make_pair(IC_IMM, -Operand.second));
297 break;
298 case IC_NOT:
299 OperandStack.push_back(std::make_pair(IC_IMM, ~Operand.second));
300 break;
301 }
302 } else {
303 assert (OperandStack.size() > 1 && "Too few operands.");
304 int64_t Val;
307 switch (Op.first) {
308 default:
310 break;
311 case IC_PLUS:
312 Val = Op1.second + Op2.second;
313 OperandStack.push_back(std::make_pair(IC_IMM, Val));
314 break;
315 case IC_MINUS:
316 Val = Op1.second - Op2.second;
317 OperandStack.push_back(std::make_pair(IC_IMM, Val));
318 break;
319 case IC_MULTIPLY:
320 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
321 "Multiply operation with an immediate and a register!");
322 Val = Op1.second * Op2.second;
323 OperandStack.push_back(std::make_pair(IC_IMM, Val));
324 break;
325 case IC_DIVIDE:
326 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
327 "Divide operation with an immediate and a register!");
328 assert (Op2.second != 0 && "Division by zero!");
329 Val = Op1.second / Op2.second;
330 OperandStack.push_back(std::make_pair(IC_IMM, Val));
331 break;
332 case IC_MOD:
333 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
334 "Modulo operation with an immediate and a register!");
335 Val = Op1.second % Op2.second;
336 OperandStack.push_back(std::make_pair(IC_IMM, Val));
337 break;
338 case IC_OR:
339 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
340 "Or operation with an immediate and a register!");
341 Val = Op1.second | Op2.second;
342 OperandStack.push_back(std::make_pair(IC_IMM, Val));
343 break;
344 case IC_XOR:
345 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
346 "Xor operation with an immediate and a register!");
347 Val = Op1.second ^ Op2.second;
348 OperandStack.push_back(std::make_pair(IC_IMM, Val));
349 break;
350 case IC_AND:
351 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
352 "And operation with an immediate and a register!");
353 Val = Op1.second & Op2.second;
354 OperandStack.push_back(std::make_pair(IC_IMM, Val));
355 break;
356 case IC_LSHIFT:
357 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
358 "Left shift operation with an immediate and a register!");
359 Val = Op1.second << Op2.second;
360 OperandStack.push_back(std::make_pair(IC_IMM, Val));
361 break;
362 case IC_RSHIFT:
363 assert (Op1.first == IC_IMM && Op2.first == IC_IMM &&
364 "Right shift operation with an immediate and a register!");
365 Val = Op1.second >> Op2.second;
366 OperandStack.push_back(std::make_pair(IC_IMM, Val));
367 break;
368 case IC_EQ:
369 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
370 "Equals operation with an immediate and a register!");
371 Val = (Op1.second == Op2.second) ? -1 : 0;
372 OperandStack.push_back(std::make_pair(IC_IMM, Val));
373 break;
374 case IC_NE:
375 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
376 "Not-equals operation with an immediate and a register!");
377 Val = (Op1.second != Op2.second) ? -1 : 0;
378 OperandStack.push_back(std::make_pair(IC_IMM, Val));
379 break;
380 case IC_LT:
381 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
382 "Less-than operation with an immediate and a register!");
383 Val = (Op1.second < Op2.second) ? -1 : 0;
384 OperandStack.push_back(std::make_pair(IC_IMM, Val));
385 break;
386 case IC_LE:
387 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
388 "Less-than-or-equal operation with an immediate and a "
389 "register!");
390 Val = (Op1.second <= Op2.second) ? -1 : 0;
391 OperandStack.push_back(std::make_pair(IC_IMM, Val));
392 break;
393 case IC_GT:
394 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
395 "Greater-than operation with an immediate and a register!");
396 Val = (Op1.second > Op2.second) ? -1 : 0;
397 OperandStack.push_back(std::make_pair(IC_IMM, Val));
398 break;
399 case IC_GE:
400 assert(Op1.first == IC_IMM && Op2.first == IC_IMM &&
401 "Greater-than-or-equal operation with an immediate and a "
402 "register!");
403 Val = (Op1.second >= Op2.second) ? -1 : 0;
404 OperandStack.push_back(std::make_pair(IC_IMM, Val));
405 break;
406 }
407 }
408 }
409 assert (OperandStack.size() == 1 && "Expected a single result.");
411 }
412 };
413
414 enum IntelExprState {
415 IES_INIT,
416 IES_OR,
417 IES_XOR,
418 IES_AND,
419 IES_EQ,
420 IES_NE,
421 IES_LT,
422 IES_LE,
423 IES_GT,
424 IES_GE,
425 IES_LSHIFT,
426 IES_RSHIFT,
427 IES_PLUS,
428 IES_MINUS,
429 IES_OFFSET,
430 IES_CAST,
431 IES_NOT,
432 IES_MULTIPLY,
433 IES_DIVIDE,
434 IES_MOD,
435 IES_LBRAC,
436 IES_RBRAC,
437 IES_LPAREN,
438 IES_RPAREN,
439 IES_REGISTER,
440 IES_INTEGER,
441 IES_ERROR
442 };
443
444 class IntelExprStateMachine {
445 IntelExprState State = IES_INIT, PrevState = IES_ERROR;
446 MCRegister BaseReg, IndexReg, TmpReg;
447 unsigned Scale = 0;
448 int64_t Imm = 0;
449 const MCExpr *Sym = nullptr;
450 StringRef SymName;
451 InfixCalculator IC;
452 InlineAsmIdentifierInfo Info;
453 short BracCount = 0;
454 bool MemExpr = false;
455 bool BracketUsed = false;
456 bool OffsetOperator = false;
457 bool AttachToOperandIdx = false;
458 bool IsPIC = false;
459 SMLoc OffsetOperatorLoc;
460 AsmTypeInfo CurType;
461
462 bool setSymRef(const MCExpr *Val, StringRef ID, StringRef &ErrMsg) {
463 if (Sym) {
464 ErrMsg = "cannot use more than one symbol in memory operand";
465 return true;
466 }
467 Sym = Val;
468 SymName = ID;
469 return false;
470 }
471
472 public:
473 IntelExprStateMachine() = default;
474
475 void addImm(int64_t imm) { Imm += imm; }
476 short getBracCount() const { return BracCount; }
477 bool isMemExpr() const { return MemExpr; }
478 bool isBracketUsed() const { return BracketUsed; }
479 bool isOffsetOperator() const { return OffsetOperator; }
480 SMLoc getOffsetLoc() const { return OffsetOperatorLoc; }
481 MCRegister getBaseReg() const { return BaseReg; }
482 MCRegister getIndexReg() const { return IndexReg; }
483 unsigned getScale() const { return Scale; }
484 const MCExpr *getSym() const { return Sym; }
485 StringRef getSymName() const { return SymName; }
486 StringRef getType() const { return CurType.Name; }
487 unsigned getSize() const { return CurType.Size; }
488 unsigned getElementSize() const { return CurType.ElementSize; }
489 unsigned getLength() const { return CurType.Length; }
490 int64_t getImm() { return Imm + IC.execute(); }
491 bool isValidEndState() const {
492 return State == IES_RBRAC || State == IES_RPAREN ||
493 State == IES_INTEGER || State == IES_REGISTER ||
494 State == IES_OFFSET;
495 }
496
497
498
499
500
501 void setAppendAfterOperand() { AttachToOperandIdx = true; }
502
503 bool isPIC() const { return IsPIC; }
504 void setPIC() { IsPIC = true; }
505
506 bool hadError() const { return State == IES_ERROR; }
507 const InlineAsmIdentifierInfo &getIdentifierInfo() const { return Info; }
508
509 bool regsUseUpError(StringRef &ErrMsg) {
510
511
512 if (IsPIC && AttachToOperandIdx)
513 ErrMsg = "Don't use 2 or more regs for mem offset in PIC model!";
514 else
515 ErrMsg = "BaseReg/IndexReg already set!";
516 return true;
517 }
518
519 void onOr() {
520 IntelExprState CurrState = State;
521 switch (State) {
522 default:
523 State = IES_ERROR;
524 break;
525 case IES_INTEGER:
526 case IES_RPAREN:
527 case IES_REGISTER:
528 State = IES_OR;
529 IC.pushOperator(IC_OR);
530 break;
531 }
532 PrevState = CurrState;
533 }
534 void onXor() {
535 IntelExprState CurrState = State;
536 switch (State) {
537 default:
538 State = IES_ERROR;
539 break;
540 case IES_INTEGER:
541 case IES_RPAREN:
542 case IES_REGISTER:
543 State = IES_XOR;
544 IC.pushOperator(IC_XOR);
545 break;
546 }
547 PrevState = CurrState;
548 }
549 void onAnd() {
550 IntelExprState CurrState = State;
551 switch (State) {
552 default:
553 State = IES_ERROR;
554 break;
555 case IES_INTEGER:
556 case IES_RPAREN:
557 case IES_REGISTER:
558 State = IES_AND;
559 IC.pushOperator(IC_AND);
560 break;
561 }
562 PrevState = CurrState;
563 }
564 void onEq() {
565 IntelExprState CurrState = State;
566 switch (State) {
567 default:
568 State = IES_ERROR;
569 break;
570 case IES_INTEGER:
571 case IES_RPAREN:
572 case IES_REGISTER:
573 State = IES_EQ;
574 IC.pushOperator(IC_EQ);
575 break;
576 }
577 PrevState = CurrState;
578 }
579 void onNE() {
580 IntelExprState CurrState = State;
581 switch (State) {
582 default:
583 State = IES_ERROR;
584 break;
585 case IES_INTEGER:
586 case IES_RPAREN:
587 case IES_REGISTER:
588 State = IES_NE;
589 IC.pushOperator(IC_NE);
590 break;
591 }
592 PrevState = CurrState;
593 }
594 void onLT() {
595 IntelExprState CurrState = State;
596 switch (State) {
597 default:
598 State = IES_ERROR;
599 break;
600 case IES_INTEGER:
601 case IES_RPAREN:
602 case IES_REGISTER:
603 State = IES_LT;
604 IC.pushOperator(IC_LT);
605 break;
606 }
607 PrevState = CurrState;
608 }
609 void onLE() {
610 IntelExprState CurrState = State;
611 switch (State) {
612 default:
613 State = IES_ERROR;
614 break;
615 case IES_INTEGER:
616 case IES_RPAREN:
617 case IES_REGISTER:
618 State = IES_LE;
619 IC.pushOperator(IC_LE);
620 break;
621 }
622 PrevState = CurrState;
623 }
624 void onGT() {
625 IntelExprState CurrState = State;
626 switch (State) {
627 default:
628 State = IES_ERROR;
629 break;
630 case IES_INTEGER:
631 case IES_RPAREN:
632 case IES_REGISTER:
633 State = IES_GT;
634 IC.pushOperator(IC_GT);
635 break;
636 }
637 PrevState = CurrState;
638 }
639 void onGE() {
640 IntelExprState CurrState = State;
641 switch (State) {
642 default:
643 State = IES_ERROR;
644 break;
645 case IES_INTEGER:
646 case IES_RPAREN:
647 case IES_REGISTER:
648 State = IES_GE;
649 IC.pushOperator(IC_GE);
650 break;
651 }
652 PrevState = CurrState;
653 }
654 void onLShift() {
655 IntelExprState CurrState = State;
656 switch (State) {
657 default:
658 State = IES_ERROR;
659 break;
660 case IES_INTEGER:
661 case IES_RPAREN:
662 case IES_REGISTER:
663 State = IES_LSHIFT;
664 IC.pushOperator(IC_LSHIFT);
665 break;
666 }
667 PrevState = CurrState;
668 }
669 void onRShift() {
670 IntelExprState CurrState = State;
671 switch (State) {
672 default:
673 State = IES_ERROR;
674 break;
675 case IES_INTEGER:
676 case IES_RPAREN:
677 case IES_REGISTER:
678 State = IES_RSHIFT;
679 IC.pushOperator(IC_RSHIFT);
680 break;
681 }
682 PrevState = CurrState;
683 }
684 bool onPlus(StringRef &ErrMsg) {
685 IntelExprState CurrState = State;
686 switch (State) {
687 default:
688 State = IES_ERROR;
689 break;
690 case IES_INTEGER:
691 case IES_RPAREN:
692 case IES_REGISTER:
693 case IES_OFFSET:
694 State = IES_PLUS;
695 IC.pushOperator(IC_PLUS);
696 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
697
698
699 if (!BaseReg) {
700 BaseReg = TmpReg;
701 } else {
702 if (IndexReg)
703 return regsUseUpError(ErrMsg);
704 IndexReg = TmpReg;
705 Scale = 0;
706 }
707 }
708 break;
709 }
710 PrevState = CurrState;
711 return false;
712 }
713 bool onMinus(StringRef &ErrMsg) {
714 IntelExprState CurrState = State;
715 switch (State) {
716 default:
717 State = IES_ERROR;
718 break;
719 case IES_OR:
720 case IES_XOR:
721 case IES_AND:
722 case IES_EQ:
723 case IES_NE:
724 case IES_LT:
725 case IES_LE:
726 case IES_GT:
727 case IES_GE:
728 case IES_LSHIFT:
729 case IES_RSHIFT:
730 case IES_PLUS:
731 case IES_NOT:
732 case IES_MULTIPLY:
733 case IES_DIVIDE:
734 case IES_MOD:
735 case IES_LPAREN:
736 case IES_RPAREN:
737 case IES_LBRAC:
738 case IES_RBRAC:
739 case IES_INTEGER:
740 case IES_REGISTER:
741 case IES_INIT:
742 case IES_OFFSET:
743 State = IES_MINUS;
744
745 if (CurrState == IES_REGISTER || CurrState == IES_RPAREN ||
746 CurrState == IES_INTEGER || CurrState == IES_RBRAC ||
747 CurrState == IES_OFFSET)
748 IC.pushOperator(IC_MINUS);
749 else if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
750
751 ErrMsg = "Scale can't be negative";
752 return true;
753 } else
754 IC.pushOperator(IC_NEG);
755 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
756
757
758 if (!BaseReg) {
759 BaseReg = TmpReg;
760 } else {
761 if (IndexReg)
762 return regsUseUpError(ErrMsg);
763 IndexReg = TmpReg;
764 Scale = 0;
765 }
766 }
767 break;
768 }
769 PrevState = CurrState;
770 return false;
771 }
772 void onNot() {
773 IntelExprState CurrState = State;
774 switch (State) {
775 default:
776 State = IES_ERROR;
777 break;
778 case IES_OR:
779 case IES_XOR:
780 case IES_AND:
781 case IES_EQ:
782 case IES_NE:
783 case IES_LT:
784 case IES_LE:
785 case IES_GT:
786 case IES_GE:
787 case IES_LSHIFT:
788 case IES_RSHIFT:
789 case IES_PLUS:
790 case IES_MINUS:
791 case IES_NOT:
792 case IES_MULTIPLY:
793 case IES_DIVIDE:
794 case IES_MOD:
795 case IES_LPAREN:
796 case IES_LBRAC:
797 case IES_INIT:
798 State = IES_NOT;
799 IC.pushOperator(IC_NOT);
800 break;
801 }
802 PrevState = CurrState;
803 }
804 bool onRegister(MCRegister Reg, StringRef &ErrMsg) {
805 IntelExprState CurrState = State;
806 switch (State) {
807 default:
808 State = IES_ERROR;
809 break;
810 case IES_PLUS:
811 case IES_LPAREN:
812 case IES_LBRAC:
813 State = IES_REGISTER;
814 TmpReg = Reg;
815 IC.pushOperand(IC_REGISTER);
816 break;
817 case IES_MULTIPLY:
818
819 if (PrevState == IES_INTEGER) {
820 if (IndexReg)
821 return regsUseUpError(ErrMsg);
822 State = IES_REGISTER;
823 IndexReg = Reg;
824
825 Scale = IC.popOperand();
827 return true;
828 IC.pushOperand(IC_IMM);
829 IC.popOperator();
830 } else {
831 State = IES_ERROR;
832 }
833 break;
834 }
835 PrevState = CurrState;
836 return false;
837 }
838 bool onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName,
839 const InlineAsmIdentifierInfo &IDInfo,
840 const AsmTypeInfo &Type, bool ParsingMSInlineAsm,
841 StringRef &ErrMsg) {
842
843 if (ParsingMSInlineAsm)
845 return onInteger(IDInfo.Enum.EnumVal, ErrMsg);
846
848 return onInteger(CE->getValue(), ErrMsg);
849 PrevState = State;
850 switch (State) {
851 default:
852 State = IES_ERROR;
853 break;
854 case IES_CAST:
855 case IES_PLUS:
856 case IES_MINUS:
857 case IES_NOT:
858 case IES_INIT:
859 case IES_LBRAC:
860 case IES_LPAREN:
861 if (setSymRef(SymRef, SymRefName, ErrMsg))
862 return true;
863 MemExpr = true;
864 State = IES_INTEGER;
865 IC.pushOperand(IC_IMM);
866 if (ParsingMSInlineAsm)
867 Info = IDInfo;
868 setTypeInfo(Type);
869 break;
870 }
871 return false;
872 }
873 bool onInteger(int64_t TmpInt, StringRef &ErrMsg) {
874 IntelExprState CurrState = State;
875 switch (State) {
876 default:
877 State = IES_ERROR;
878 break;
879 case IES_PLUS:
880 case IES_MINUS:
881 case IES_NOT:
882 case IES_OR:
883 case IES_XOR:
884 case IES_AND:
885 case IES_EQ:
886 case IES_NE:
887 case IES_LT:
888 case IES_LE:
889 case IES_GT:
890 case IES_GE:
891 case IES_LSHIFT:
892 case IES_RSHIFT:
893 case IES_DIVIDE:
894 case IES_MOD:
895 case IES_MULTIPLY:
896 case IES_LPAREN:
897 case IES_INIT:
898 case IES_LBRAC:
899 State = IES_INTEGER;
900 if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) {
901
902 if (IndexReg)
903 return regsUseUpError(ErrMsg);
904 IndexReg = TmpReg;
905 Scale = TmpInt;
907 return true;
908
909 IC.popOperator();
910 } else {
911 IC.pushOperand(IC_IMM, TmpInt);
912 }
913 break;
914 }
915 PrevState = CurrState;
916 return false;
917 }
918 void onStar() {
919 PrevState = State;
920 switch (State) {
921 default:
922 State = IES_ERROR;
923 break;
924 case IES_INTEGER:
925 case IES_REGISTER:
926 case IES_RPAREN:
927 State = IES_MULTIPLY;
928 IC.pushOperator(IC_MULTIPLY);
929 break;
930 }
931 }
932 void onDivide() {
933 PrevState = State;
934 switch (State) {
935 default:
936 State = IES_ERROR;
937 break;
938 case IES_INTEGER:
939 case IES_RPAREN:
940 State = IES_DIVIDE;
941 IC.pushOperator(IC_DIVIDE);
942 break;
943 }
944 }
945 void onMod() {
946 PrevState = State;
947 switch (State) {
948 default:
949 State = IES_ERROR;
950 break;
951 case IES_INTEGER:
952 case IES_RPAREN:
953 State = IES_MOD;
954 IC.pushOperator(IC_MOD);
955 break;
956 }
957 }
958 bool onLBrac() {
959 if (BracCount)
960 return true;
961 PrevState = State;
962 switch (State) {
963 default:
964 State = IES_ERROR;
965 break;
966 case IES_RBRAC:
967 case IES_INTEGER:
968 case IES_RPAREN:
969 State = IES_PLUS;
970 IC.pushOperator(IC_PLUS);
971 CurType.Length = 1;
972 CurType.Size = CurType.ElementSize;
973 break;
974 case IES_INIT:
975 case IES_CAST:
976 assert(!BracCount && "BracCount should be zero on parsing's start");
977 State = IES_LBRAC;
978 break;
979 }
980 MemExpr = true;
981 BracketUsed = true;
982 BracCount++;
983 return false;
984 }
985 bool onRBrac(StringRef &ErrMsg) {
986 IntelExprState CurrState = State;
987 switch (State) {
988 default:
989 State = IES_ERROR;
990 break;
991 case IES_INTEGER:
992 case IES_OFFSET:
993 case IES_REGISTER:
994 case IES_RPAREN:
995 if (BracCount-- != 1) {
996 ErrMsg = "unexpected bracket encountered";
997 return true;
998 }
999 State = IES_RBRAC;
1000 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
1001
1002
1003 if (!BaseReg) {
1004 BaseReg = TmpReg;
1005 } else {
1006 if (IndexReg)
1007 return regsUseUpError(ErrMsg);
1008 IndexReg = TmpReg;
1009 Scale = 0;
1010 }
1011 }
1012 break;
1013 }
1014 PrevState = CurrState;
1015 return false;
1016 }
1017 void onLParen() {
1018 IntelExprState CurrState = State;
1019 switch (State) {
1020 default:
1021 State = IES_ERROR;
1022 break;
1023 case IES_PLUS:
1024 case IES_MINUS:
1025 case IES_NOT:
1026 case IES_OR:
1027 case IES_XOR:
1028 case IES_AND:
1029 case IES_EQ:
1030 case IES_NE:
1031 case IES_LT:
1032 case IES_LE:
1033 case IES_GT:
1034 case IES_GE:
1035 case IES_LSHIFT:
1036 case IES_RSHIFT:
1037 case IES_MULTIPLY:
1038 case IES_DIVIDE:
1039 case IES_MOD:
1040 case IES_LPAREN:
1041 case IES_INIT:
1042 case IES_LBRAC:
1043 State = IES_LPAREN;
1044 IC.pushOperator(IC_LPAREN);
1045 break;
1046 }
1047 PrevState = CurrState;
1048 }
1049 bool onRParen(StringRef &ErrMsg) {
1050 IntelExprState CurrState = State;
1051 switch (State) {
1052 default:
1053 State = IES_ERROR;
1054 break;
1055 case IES_INTEGER:
1056 case IES_OFFSET:
1057 case IES_REGISTER:
1058 case IES_RBRAC:
1059 case IES_RPAREN:
1060 State = IES_RPAREN;
1061
1062
1063
1064
1065 if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) {
1066
1067
1068 if (!BaseReg) {
1069 BaseReg = TmpReg;
1070 } else {
1071 if (IndexReg)
1072 return regsUseUpError(ErrMsg);
1073 IndexReg = TmpReg;
1074 Scale = 0;
1075 }
1076 }
1077 IC.pushOperator(IC_RPAREN);
1078 break;
1079 }
1080 PrevState = CurrState;
1081 return false;
1082 }
1083 bool onOffset(const MCExpr *Val, SMLoc OffsetLoc, StringRef ID,
1084 const InlineAsmIdentifierInfo &IDInfo,
1085 bool ParsingMSInlineAsm, StringRef &ErrMsg) {
1086 PrevState = State;
1087 switch (State) {
1088 default:
1089 ErrMsg = "unexpected offset operator expression";
1090 return true;
1091 case IES_PLUS:
1092 case IES_INIT:
1093 case IES_LBRAC:
1094 if (setSymRef(Val, ID, ErrMsg))
1095 return true;
1096 OffsetOperator = true;
1097 OffsetOperatorLoc = OffsetLoc;
1098 State = IES_OFFSET;
1099
1100
1101 IC.pushOperand(IC_IMM);
1102 if (ParsingMSInlineAsm) {
1103 Info = IDInfo;
1104 }
1105 break;
1106 }
1107 return false;
1108 }
1109 void onCast(AsmTypeInfo Info) {
1110 PrevState = State;
1111 switch (State) {
1112 default:
1113 State = IES_ERROR;
1114 break;
1115 case IES_LPAREN:
1116 setTypeInfo(Info);
1117 State = IES_CAST;
1118 break;
1119 }
1120 }
1121 void setTypeInfo(AsmTypeInfo Type) { CurType = Type; }
1122 };
1123
1124 bool Error(SMLoc L, const Twine &Msg, SMRange Range = {},
1125 bool MatchingInlineAsm = false) {
1126 MCAsmParser &Parser = getParser();
1127 if (MatchingInlineAsm) {
1128 return false;
1129 }
1131 }
1132
1133 bool MatchRegisterByName(MCRegister &RegNo, StringRef RegName, SMLoc StartLoc,
1134 SMLoc EndLoc);
1135 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1136 bool RestoreOnFailure);
1137
1138 std::unique_ptr DefaultMemSIOperand(SMLoc Loc);
1139 std::unique_ptr DefaultMemDIOperand(SMLoc Loc);
1140 bool IsSIReg(MCRegister Reg);
1141 MCRegister GetSIDIForRegClass(unsigned RegClassID, bool IsSIReg);
1142 void
1143 AddDefaultSrcDestOperands(OperandVector &Operands,
1144 std::unique_ptrllvm::MCParsedAsmOperand &&Src,
1145 std::unique_ptrllvm::MCParsedAsmOperand &&Dst);
1146 bool VerifyAndAdjustOperands(OperandVector &OrigOperands,
1148 bool parseOperand(OperandVector &Operands, StringRef Name);
1150 bool parseIntelOperand(OperandVector &Operands, StringRef Name);
1151 bool ParseIntelOffsetOperator(const MCExpr *&Val, StringRef &ID,
1152 InlineAsmIdentifierInfo &Info, SMLoc &End);
1153 bool ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End);
1154 unsigned IdentifyIntelInlineAsmOperator(StringRef Name);
1155 unsigned ParseIntelInlineAsmOperator(unsigned OpKind);
1156 unsigned IdentifyMasmOperator(StringRef Name);
1157 bool ParseMasmOperator(unsigned OpKind, int64_t &Val);
1158 bool ParseRoundingModeOp(SMLoc Start, OperandVector &Operands);
1160 bool ParseIntelNamedOperator(StringRef Name, IntelExprStateMachine &SM,
1161 bool &ParseError, SMLoc &End);
1162 bool ParseMasmNamedOperator(StringRef Name, IntelExprStateMachine &SM,
1163 bool &ParseError, SMLoc &End);
1164 void RewriteIntelExpression(IntelExprStateMachine &SM, SMLoc Start,
1165 SMLoc End);
1166 bool ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
1167 bool ParseIntelInlineAsmIdentifier(const MCExpr *&Val, StringRef &Identifier,
1168 InlineAsmIdentifierInfo &Info,
1169 bool IsUnevaluatedOperand, SMLoc &End,
1170 bool IsParsingOffsetOperator = false);
1172 IntelExprStateMachine &SM);
1173
1174 bool ParseMemOperand(MCRegister SegReg, const MCExpr *Disp, SMLoc StartLoc,
1176
1177 X86::CondCode ParseConditionCode(StringRef CCode);
1178
1179 bool ParseIntelMemoryOperandSize(unsigned &Size, StringRef *SizeStr);
1180 bool CreateMemForMSInlineAsm(MCRegister SegReg, const MCExpr *Disp,
1181 MCRegister BaseReg, MCRegister IndexReg,
1182 unsigned Scale, bool NonAbsMem, SMLoc Start,
1183 SMLoc End, unsigned Size, StringRef Identifier,
1184 const InlineAsmIdentifierInfo &Info,
1186
1187 bool parseDirectiveArch();
1188 bool parseDirectiveNops(SMLoc L);
1189 bool parseDirectiveEven(SMLoc L);
1190 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
1191
1192
1193 bool parseDirectiveFPOProc(SMLoc L);
1194 bool parseDirectiveFPOSetFrame(SMLoc L);
1195 bool parseDirectiveFPOPushReg(SMLoc L);
1196 bool parseDirectiveFPOStackAlloc(SMLoc L);
1197 bool parseDirectiveFPOStackAlign(SMLoc L);
1198 bool parseDirectiveFPOEndPrologue(SMLoc L);
1199 bool parseDirectiveFPOEndProc(SMLoc L);
1200
1201
1202 bool parseSEHRegisterNumber(unsigned RegClassID, MCRegister &RegNo);
1203 bool parseDirectiveSEHPushReg(SMLoc);
1204 bool parseDirectiveSEHSetFrame(SMLoc);
1205 bool parseDirectiveSEHSaveReg(SMLoc);
1206 bool parseDirectiveSEHSaveXMM(SMLoc);
1207 bool parseDirectiveSEHPushFrame(SMLoc);
1208
1209 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
1210
1211 bool validateInstruction(MCInst &Inst, const OperandVector &Ops);
1212 bool processInstruction(MCInst &Inst, const OperandVector &Ops);
1213
1214
1215 void emitWarningForSpecialLVIInstruction(SMLoc Loc);
1216 void applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out);
1217 void applyLVILoadHardeningMitigation(MCInst &Inst, MCStreamer &Out);
1218
1219
1220
1222
1223 bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1225 uint64_t &ErrorInfo,
1226 bool MatchingInlineAsm) override;
1227
1228 void MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op, OperandVector &Operands,
1229 MCStreamer &Out, bool MatchingInlineAsm);
1230
1231 bool ErrorMissingFeature(SMLoc IDLoc, const FeatureBitset &MissingFeatures,
1232 bool MatchingInlineAsm);
1233
1234 bool matchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode, MCInst &Inst,
1236 uint64_t &ErrorInfo, bool MatchingInlineAsm);
1237
1238 bool matchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode, MCInst &Inst,
1240 uint64_t &ErrorInfo,
1241 bool MatchingInlineAsm);
1242
1243 bool omitRegisterFromClobberLists(MCRegister Reg) override;
1244
1245
1246
1247
1248 bool HandleAVX512Operand(OperandVector &Operands);
1249
1250 bool ParseZ(std::unique_ptr &Z, SMLoc StartLoc);
1251
1252 bool is64BitMode() const {
1253
1254 return getSTI().hasFeature(X86::Is64Bit);
1255 }
1256 bool is32BitMode() const {
1257
1258 return getSTI().hasFeature(X86::Is32Bit);
1259 }
1260 bool is16BitMode() const {
1261
1262 return getSTI().hasFeature(X86::Is16Bit);
1263 }
1264 void SwitchMode(unsigned mode) {
1265 MCSubtargetInfo &STI = copySTI();
1266 FeatureBitset AllModes({X86::Is64Bit, X86::Is32Bit, X86::Is16Bit});
1267 FeatureBitset OldMode = STI.getFeatureBits() & AllModes;
1268 FeatureBitset FB = ComputeAvailableFeatures(
1270 setAvailableFeatures(FB);
1271
1273 }
1274
1275 unsigned getPointerWidth() {
1276 if (is16BitMode()) return 16;
1277 if (is32BitMode()) return 32;
1278 if (is64BitMode()) return 64;
1280 }
1281
1282 bool isParsingIntelSyntax() {
1283 return getParser().getAssemblerDialect();
1284 }
1285
1286
1287
1288
1289#define GET_ASSEMBLER_HEADER
1290#include "X86GenAsmMatcher.inc"
1291
1292
1293
1294public:
1295 enum X86MatchResultTy {
1296 Match_Unsupported = FIRST_TARGET_MATCH_RESULT_TY,
1297#define GET_OPERAND_DIAGNOSTIC_TYPES
1298#include "X86GenAsmMatcher.inc"
1299 };
1300
1301 X86AsmParser(const MCSubtargetInfo &sti, MCAsmParser &Parser,
1302 const MCInstrInfo &mii, const MCTargetOptions &Options)
1303 : MCTargetAsmParser(Options, sti, mii), InstInfo(nullptr),
1304 Code16GCC(false) {
1305
1307
1308
1309 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
1310 }
1311
1312 bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
1313 ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
1314 SMLoc &EndLoc) override;
1315
1316 bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) override;
1317
1318 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
1319 SMLoc NameLoc, OperandVector &Operands) override;
1320
1321 bool ParseDirective(AsmToken DirectiveID) override;
1322};
1323}
1324
1325#define GET_REGISTER_MATCHER
1326#define GET_SUBTARGET_FEATURE_NAME
1327#include "X86GenAsmMatcher.inc"
1328
1330 MCRegister IndexReg, unsigned Scale,
1331 bool Is64BitMode,
1333
1334
1335
1336
1337 if (BaseReg &&
1338 !(BaseReg == X86::RIP || BaseReg == X86::EIP ||
1339 X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) ||
1340 X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) ||
1341 X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg))) {
1342 ErrMsg = "invalid base+index expression";
1343 return true;
1344 }
1345
1346 if (IndexReg &&
1347 !(IndexReg == X86::EIZ || IndexReg == X86::RIZ ||
1348 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
1349 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
1350 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg) ||
1351 X86MCRegisterClasses[X86::VR128XRegClassID].contains(IndexReg) ||
1352 X86MCRegisterClasses[X86::VR256XRegClassID].contains(IndexReg) ||
1353 X86MCRegisterClasses[X86::VR512RegClassID].contains(IndexReg))) {
1354 ErrMsg = "invalid base+index expression";
1355 return true;
1356 }
1357
1358 if (((BaseReg == X86::RIP || BaseReg == X86::EIP) && IndexReg) ||
1359 IndexReg == X86::EIP || IndexReg == X86::RIP || IndexReg == X86::ESP ||
1360 IndexReg == X86::RSP) {
1361 ErrMsg = "invalid base+index expression";
1362 return true;
1363 }
1364
1365
1366
1367 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
1368 (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP &&
1369 BaseReg != X86::SI && BaseReg != X86::DI))) {
1370 ErrMsg = "invalid 16-bit base register";
1371 return true;
1372 }
1373
1374 if (!BaseReg &&
1375 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) {
1376 ErrMsg = "16-bit memory operand may not include only index register";
1377 return true;
1378 }
1379
1380 if (BaseReg && IndexReg) {
1381 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&
1382 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
1383 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
1384 IndexReg == X86::EIZ)) {
1385 ErrMsg = "base register is 64-bit, but index register is not";
1386 return true;
1387 }
1388 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) &&
1389 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
1390 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg) ||
1391 IndexReg == X86::RIZ)) {
1392 ErrMsg = "base register is 32-bit, but index register is not";
1393 return true;
1394 }
1395 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) {
1396 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
1397 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) {
1398 ErrMsg = "base register is 16-bit, but index register is not";
1399 return true;
1400 }
1401 if ((BaseReg != X86::BX && BaseReg != X86::BP) ||
1402 (IndexReg != X86::SI && IndexReg != X86::DI)) {
1403 ErrMsg = "invalid 16-bit base/index register combination";
1404 return true;
1405 }
1406 }
1407 }
1408
1409
1410 if (!Is64BitMode && (BaseReg == X86::RIP || BaseReg == X86::EIP)) {
1411 ErrMsg = "IP-relative addressing requires 64-bit mode";
1412 return true;
1413 }
1414
1416}
1417
1420
1421
1422 RegName.consume_front("%");
1423
1425
1426
1427 if (!RegNo)
1429
1430
1431
1432 if (isParsingMSInlineAsm() && isParsingIntelSyntax() &&
1433 (RegNo == X86::EFLAGS || RegNo == X86::MXCSR))
1434 RegNo = MCRegister();
1435
1436 if (!is64BitMode()) {
1437
1438
1439
1440 if (RegNo == X86::RIZ || RegNo == X86::RIP ||
1441 X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||
1444 return Error(StartLoc,
1445 "register %" + RegName + " is only available in 64-bit mode",
1446 SMRange(StartLoc, EndLoc));
1447 }
1448 }
1449
1451 UseApxExtendedReg = true;
1452
1453
1454
1455 if (!RegNo && RegName.starts_with("db")) {
1456 if (RegName.size() == 3) {
1458 case '0':
1459 RegNo = X86::DR0;
1460 break;
1461 case '1':
1462 RegNo = X86::DR1;
1463 break;
1464 case '2':
1465 RegNo = X86::DR2;
1466 break;
1467 case '3':
1468 RegNo = X86::DR3;
1469 break;
1470 case '4':
1471 RegNo = X86::DR4;
1472 break;
1473 case '5':
1474 RegNo = X86::DR5;
1475 break;
1476 case '6':
1477 RegNo = X86::DR6;
1478 break;
1479 case '7':
1480 RegNo = X86::DR7;
1481 break;
1482 case '8':
1483 RegNo = X86::DR8;
1484 break;
1485 case '9':
1486 RegNo = X86::DR9;
1487 break;
1488 }
1489 } else if (RegName.size() == 4 && RegName[2] == '1') {
1491 case '0':
1492 RegNo = X86::DR10;
1493 break;
1494 case '1':
1495 RegNo = X86::DR11;
1496 break;
1497 case '2':
1498 RegNo = X86::DR12;
1499 break;
1500 case '3':
1501 RegNo = X86::DR13;
1502 break;
1503 case '4':
1504 RegNo = X86::DR14;
1505 break;
1506 case '5':
1507 RegNo = X86::DR15;
1508 break;
1509 }
1510 }
1511 }
1512
1513 if (!RegNo) {
1514 if (isParsingIntelSyntax())
1515 return true;
1516 return Error(StartLoc, "invalid register name", SMRange(StartLoc, EndLoc));
1517 }
1518 return false;
1519}
1520
1521bool X86AsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
1522 SMLoc &EndLoc, bool RestoreOnFailure) {
1523 MCAsmParser &Parser = getParser();
1524 AsmLexer &Lexer = getLexer();
1525 RegNo = MCRegister();
1526
1528 auto OnFailure = [RestoreOnFailure, &Lexer, &Tokens]() {
1529 if (RestoreOnFailure) {
1530 while (!Tokens.empty()) {
1532 }
1533 }
1534 };
1535
1536 const AsmToken &PercentTok = Parser.getTok();
1537 StartLoc = PercentTok.getLoc();
1538
1539
1540
1543 Parser.Lex();
1544 }
1545
1546 const AsmToken &Tok = Parser.getTok();
1548
1550 OnFailure();
1551 if (isParsingIntelSyntax()) return true;
1552 return Error(StartLoc, "invalid register name",
1553 SMRange(StartLoc, EndLoc));
1554 }
1555
1556 if (MatchRegisterByName(RegNo, Tok.getString(), StartLoc, EndLoc)) {
1557 OnFailure();
1558 return true;
1559 }
1560
1561
1562 if (RegNo == X86::ST0) {
1564 Parser.Lex();
1565
1566
1568 return false;
1569
1571 Parser.Lex();
1572
1573 const AsmToken &IntTok = Parser.getTok();
1575 OnFailure();
1576 return Error(IntTok.getLoc(), "expected stack index");
1577 }
1579 case 0: RegNo = X86::ST0; break;
1580 case 1: RegNo = X86::ST1; break;
1581 case 2: RegNo = X86::ST2; break;
1582 case 3: RegNo = X86::ST3; break;
1583 case 4: RegNo = X86::ST4; break;
1584 case 5: RegNo = X86::ST5; break;
1585 case 6: RegNo = X86::ST6; break;
1586 case 7: RegNo = X86::ST7; break;
1587 default:
1588 OnFailure();
1589 return Error(IntTok.getLoc(), "invalid stack index");
1590 }
1591
1592
1594 Parser.Lex();
1596 OnFailure();
1598 }
1599
1601 Parser.Lex();
1602 return false;
1603 }
1604
1606
1607 if (!RegNo) {
1608 OnFailure();
1609 if (isParsingIntelSyntax()) return true;
1610 return Error(StartLoc, "invalid register name",
1611 SMRange(StartLoc, EndLoc));
1612 }
1613
1614 Parser.Lex();
1615 return false;
1616}
1617
1618bool X86AsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
1619 SMLoc &EndLoc) {
1620 return ParseRegister(Reg, StartLoc, EndLoc, false);
1621}
1622
1623ParseStatus X86AsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
1624 SMLoc &EndLoc) {
1625 bool Result = ParseRegister(Reg, StartLoc, EndLoc, true);
1626 bool PendingErrors = getParser().hasPendingError();
1627 getParser().clearPendingErrors();
1628 if (PendingErrors)
1630 if (Result)
1633}
1634
1635std::unique_ptr X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
1636 bool Parse32 = is32BitMode() || Code16GCC;
1637 MCRegister Basereg =
1638 is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
1641 Basereg, 0, 1,
1642 Loc, Loc, 0);
1643}
1644
1645std::unique_ptr X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
1646 bool Parse32 = is32BitMode() || Code16GCC;
1647 MCRegister Basereg =
1648 is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
1651 Basereg, 0, 1,
1652 Loc, Loc, 0);
1653}
1654
1655bool X86AsmParser::IsSIReg(MCRegister Reg) {
1657 default: llvm_unreachable("Only (R|E)SI and (R|E)DI are expected!");
1658 case X86::RSI:
1659 case X86::ESI:
1660 case X86::SI:
1661 return true;
1662 case X86::RDI:
1663 case X86::EDI:
1664 case X86::DI:
1665 return false;
1666 }
1667}
1668
1669MCRegister X86AsmParser::GetSIDIForRegClass(unsigned RegClassID, bool IsSIReg) {
1670 switch (RegClassID) {
1672 case X86::GR64RegClassID:
1673 return IsSIReg ? X86::RSI : X86::RDI;
1674 case X86::GR32RegClassID:
1675 return IsSIReg ? X86::ESI : X86::EDI;
1676 case X86::GR16RegClassID:
1677 return IsSIReg ? X86::SI : X86::DI;
1678 }
1679}
1680
1681void X86AsmParser::AddDefaultSrcDestOperands(
1682 OperandVector& Operands, std::unique_ptrllvm::MCParsedAsmOperand &&Src,
1683 std::unique_ptrllvm::MCParsedAsmOperand &&Dst) {
1684 if (isParsingIntelSyntax()) {
1685 Operands.push_back(std::move(Dst));
1686 Operands.push_back(std::move(Src));
1687 }
1688 else {
1689 Operands.push_back(std::move(Src));
1690 Operands.push_back(std::move(Dst));
1691 }
1692}
1693
1694bool X86AsmParser::VerifyAndAdjustOperands(OperandVector &OrigOperands,
1696
1697 if (OrigOperands.size() > 1) {
1698
1699 assert(OrigOperands.size() == FinalOperands.size() + 1 &&
1700 "Operand size mismatch");
1701
1703
1704 int RegClassID = -1;
1705 for (unsigned int i = 0; i < FinalOperands.size(); ++i) {
1706 X86Operand &OrigOp = static_cast<X86Operand &>(*OrigOperands[i + 1]);
1707 X86Operand &FinalOp = static_cast<X86Operand &>(*FinalOperands[i]);
1708
1709 if (FinalOp.isReg() &&
1711
1712 return false;
1713
1714 if (FinalOp.isMem()) {
1715
1716 if (!OrigOp.isMem())
1717
1718 return false;
1719
1720 MCRegister OrigReg = OrigOp.Mem.BaseReg;
1721 MCRegister FinalReg = FinalOp.Mem.BaseReg;
1722
1723
1724
1725 if (RegClassID != -1 &&
1726 !X86MCRegisterClasses[RegClassID].contains(OrigReg)) {
1728 "mismatching source and destination index registers");
1729 }
1730
1731 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(OrigReg))
1732 RegClassID = X86::GR64RegClassID;
1733 else if (X86MCRegisterClasses[X86::GR32RegClassID].contains(OrigReg))
1734 RegClassID = X86::GR32RegClassID;
1735 else if (X86MCRegisterClasses[X86::GR16RegClassID].contains(OrigReg))
1736 RegClassID = X86::GR16RegClassID;
1737 else
1738
1739
1740 return false;
1741
1742 bool IsSI = IsSIReg(FinalReg);
1743 FinalReg = GetSIDIForRegClass(RegClassID, IsSI);
1744
1745 if (FinalReg != OrigReg) {
1746 std::string RegName = IsSI ? "ES:(R|E)SI" : "ES:(R|E)DI";
1747 Warnings.push_back(std::make_pair(
1749 "memory operand is only for determining the size, " + RegName +
1750 " will be used for the location"));
1751 }
1752
1756 }
1757 }
1758
1759
1760
1761 for (auto &WarningMsg : Warnings) {
1762 Warning(WarningMsg.first, WarningMsg.second);
1763 }
1764
1765
1766 for (unsigned int i = 0; i < FinalOperands.size(); ++i)
1768 }
1769
1770 for (auto &Op : FinalOperands)
1772
1773 return false;
1774}
1775
1776bool X86AsmParser::parseOperand(OperandVector &Operands, StringRef Name) {
1777 if (isParsingIntelSyntax())
1778 return parseIntelOperand(Operands, Name);
1779
1780 return parseATTOperand(Operands);
1781}
1782
1783bool X86AsmParser::CreateMemForMSInlineAsm(
1784 MCRegister SegReg, const MCExpr *Disp, MCRegister BaseReg,
1785 MCRegister IndexReg, unsigned Scale, bool NonAbsMem, SMLoc Start, SMLoc End,
1786 unsigned Size, StringRef Identifier, const InlineAsmIdentifierInfo &Info,
1788
1789
1791
1792
1794 End, Size, Identifier,
1795 Info.Label.Decl));
1796 return false;
1797 }
1798
1799
1800
1801 unsigned FrontendSize = 0;
1802 void *Decl = nullptr;
1803 bool IsGlobalLV = false;
1805
1806 FrontendSize = Info.Var.Type * 8;
1807 Decl = Info.Var.Decl;
1808 IsGlobalLV = Info.Var.IsGlobalLV;
1809 }
1810
1811
1812 if (IsGlobalLV) {
1813 if (BaseReg || IndexReg) {
1815 End, Size, Identifier, Decl, 0,
1816 BaseReg && IndexReg));
1817 return false;
1818 }
1819 if (NonAbsMem)
1820 BaseReg = 1;
1821 }
1823 getPointerWidth(), SegReg, Disp, BaseReg, IndexReg, Scale, Start, End,
1825 X86::RIP, Identifier, Decl, FrontendSize));
1826 return false;
1827}
1828
1829
1830
1831
1832bool X86AsmParser::ParseIntelNamedOperator(StringRef Name,
1833 IntelExprStateMachine &SM,
1834 bool &ParseError, SMLoc &End) {
1835
1836
1837 if (Name != Name.lower() && Name != Name.upper() &&
1838 !getParser().isParsingMasm())
1839 return false;
1840 if (Name.equals_insensitive("not")) {
1841 SM.onNot();
1842 } else if (Name.equals_insensitive("or")) {
1843 SM.onOr();
1844 } else if (Name.equals_insensitive("shl")) {
1845 SM.onLShift();
1846 } else if (Name.equals_insensitive("shr")) {
1847 SM.onRShift();
1848 } else if (Name.equals_insensitive("xor")) {
1849 SM.onXor();
1850 } else if (Name.equals_insensitive("and")) {
1851 SM.onAnd();
1852 } else if (Name.equals_insensitive("mod")) {
1853 SM.onMod();
1854 } else if (Name.equals_insensitive("offset")) {
1855 SMLoc OffsetLoc = getTok().getLoc();
1856 const MCExpr *Val = nullptr;
1857 StringRef ID;
1858 InlineAsmIdentifierInfo Info;
1860 if (ParseError)
1861 return true;
1862 StringRef ErrMsg;
1864 SM.onOffset(Val, OffsetLoc, ID, Info, isParsingMSInlineAsm(), ErrMsg);
1865 if (ParseError)
1867 } else {
1868 return false;
1869 }
1870 if (.equals_insensitive("offset"))
1871 End = consumeToken();
1872 return true;
1873}
1874bool X86AsmParser::ParseMasmNamedOperator(StringRef Name,
1875 IntelExprStateMachine &SM,
1876 bool &ParseError, SMLoc &End) {
1877 if (Name.equals_insensitive("eq")) {
1878 SM.onEq();
1879 } else if (Name.equals_insensitive("ne")) {
1880 SM.onNE();
1881 } else if (Name.equals_insensitive("lt")) {
1882 SM.onLT();
1883 } else if (Name.equals_insensitive("le")) {
1884 SM.onLE();
1885 } else if (Name.equals_insensitive("gt")) {
1886 SM.onGT();
1887 } else if (Name.equals_insensitive("ge")) {
1888 SM.onGE();
1889 } else {
1890 return false;
1891 }
1892 End = consumeToken();
1893 return true;
1894}
1895
1896
1897
1899 IntelExprStateMachine &SM) {
1901 return;
1902
1903 SM.setAppendAfterOperand();
1904}
1905
1906bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
1907 MCAsmParser &Parser = getParser();
1908 StringRef ErrMsg;
1909
1911
1912 if (getContext().getObjectFileInfo()->isPositionIndependent())
1913 SM.setPIC();
1914
1915 bool Done = false;
1916 while () {
1917
1918
1919 const AsmToken &Tok = Parser.getTok();
1920
1921 bool UpdateLocLex = true;
1923
1924 switch (TK) {
1925 default:
1926 if ((Done = SM.isValidEndState()))
1927 break;
1928 return Error(Tok.getLoc(), "unknown token in expression");
1930 return Error(getLexer().getErrLoc(), getLexer().getErr());
1931 break;
1933
1934 UpdateLocLex = false;
1935 if (ParseIntelDotOperator(SM, End))
1936 return true;
1937 break;
1940 if ((Done = SM.isValidEndState()))
1941 break;
1942 return Error(Tok.getLoc(), "unknown token in expression");
1943 }
1944
1945 Lex();
1946 UpdateLocLex = false;
1947 if (ParseIntelDotOperator(SM, End))
1948 return true;
1949 break;
1952 if ((Done = SM.isValidEndState()))
1953 break;
1954 return Error(Tok.getLoc(), "unknown token in expression");
1955 }
1956 [[fallthrough]];
1959
1960 SMLoc ValueLoc = Tok.getLoc();
1961 int64_t Res;
1962 const MCExpr *Val;
1964 return true;
1965 UpdateLocLex = false;
1966 if (!Val->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
1967 return Error(ValueLoc, "expected absolute value");
1968 if (SM.onInteger(Res, ErrMsg))
1969 return Error(ValueLoc, ErrMsg);
1970 break;
1971 }
1972 [[fallthrough]];
1973 }
1976 SMLoc IdentLoc = Tok.getLoc();
1978 UpdateLocLex = false;
1980 size_t DotOffset = Identifier.find_first_of('.');
1982 consumeToken();
1984 StringRef Dot = Identifier.substr(DotOffset, 1);
1985 StringRef RHS = Identifier.substr(DotOffset + 1);
1986 if (.empty()) {
1988 }
1990 if (.empty()) {
1992 }
1993 break;
1994 }
1995 }
1996
1998 const AsmToken &NextTok = getLexer().peekTok();
2001 AsmTypeInfo Info;
2003 return Error(Tok.getLoc(), "unknown type");
2004 SM.onCast(Info);
2005
2006 consumeToken();
2007 End = consumeToken();
2008 break;
2009 }
2010 }
2011
2012 MCRegister Reg;
2014 if (!ParseRegister(Reg, IdentLoc, End, true)) {
2015 if (SM.onRegister(Reg, ErrMsg))
2016 return Error(IdentLoc, ErrMsg);
2017 break;
2018 }
2020 const std::pair<StringRef, StringRef> IDField =
2022 const StringRef ID = IDField.first, Field = IDField.second;
2024 if (.empty() &&
2025 !MatchRegisterByName(Reg, ID, IdentLoc, IDEndLoc)) {
2026 if (SM.onRegister(Reg, ErrMsg))
2027 return Error(IdentLoc, ErrMsg);
2028
2029 AsmFieldInfo Info;
2032 return Error(FieldStartLoc, "unknown offset");
2033 else if (SM.onPlus(ErrMsg))
2034 return Error(getTok().getLoc(), ErrMsg);
2035 else if (SM.onInteger(Info.Offset, ErrMsg))
2036 return Error(IdentLoc, ErrMsg);
2037 SM.setTypeInfo(Info.Type);
2038
2039 End = consumeToken();
2040 break;
2041 }
2042 }
2043 }
2044
2046 if (ParseIntelNamedOperator(Identifier, SM, ParseError, End)) {
2047 if (ParseError)
2048 return true;
2049 break;
2050 }
2052 ParseMasmNamedOperator(Identifier, SM, ParseError, End)) {
2053 if (ParseError)
2054 return true;
2055 break;
2056 }
2057
2058 InlineAsmIdentifierInfo Info;
2059 AsmFieldInfo FieldInfo;
2060 const MCExpr *Val;
2061 if (isParsingMSInlineAsm() || Parser.isParsingMasm()) {
2062
2065 if (ParseIntelDotOperator(SM, End))
2066 return true;
2067 break;
2068 }
2069 }
2070 if (isParsingMSInlineAsm()) {
2071
2072 if (unsigned OpKind = IdentifyIntelInlineAsmOperator(Identifier)) {
2073 if (int64_t Val = ParseIntelInlineAsmOperator(OpKind)) {
2074 if (SM.onInteger(Val, ErrMsg))
2075 return Error(IdentLoc, ErrMsg);
2076 } else {
2077 return true;
2078 }
2079 break;
2080 }
2081
2082
2084 return Error(IdentLoc, "expected identifier");
2085 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info, false, End))
2086 return true;
2087 else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.Type,
2088 true, ErrMsg))
2089 return Error(IdentLoc, ErrMsg);
2090 break;
2091 }
2093 if (unsigned OpKind = IdentifyMasmOperator(Identifier)) {
2094 int64_t Val;
2095 if (ParseMasmOperator(OpKind, Val))
2096 return true;
2097 if (SM.onInteger(Val, ErrMsg))
2098 return Error(IdentLoc, ErrMsg);
2099 break;
2100 }
2101 if (!getParser().lookUpType(Identifier, FieldInfo.Type)) {
2102
2103 Lex();
2104 bool EndDot = parseOptionalToken(AsmToken::Dot);
2106 getTok().getString().starts_with("."))) {
2107 getParser().parseIdentifier(Identifier);
2108 if (!EndDot)
2110 EndDot = Identifier.consume_back(".");
2111 if (getParser().lookUpField(FieldInfo.Type.Name, Identifier,
2112 FieldInfo)) {
2113 SMLoc IDEnd =
2115 return Error(IdentLoc, "Unable to lookup field reference!",
2116 SMRange(IdentLoc, IDEnd));
2117 }
2118 if (!EndDot)
2120 }
2121 if (SM.onInteger(FieldInfo.Offset, ErrMsg))
2122 return Error(IdentLoc, ErrMsg);
2123 break;
2124 }
2125 }
2126 if (getParser().parsePrimaryExpr(Val, End, &FieldInfo.Type)) {
2127 return Error(Tok.getLoc(), "Unexpected identifier!");
2128 } else if (SM.onIdentifierExpr(Val, Identifier, Info, FieldInfo.Type,
2129 false, ErrMsg)) {
2130 return Error(IdentLoc, ErrMsg);
2131 }
2132 break;
2133 }
2135
2136 SMLoc Loc = getTok().getLoc();
2137 int64_t IntVal = getTok().getIntVal();
2138 End = consumeToken();
2139 UpdateLocLex = false;
2141 StringRef IDVal = getTok().getString();
2142 if (IDVal == "f" || IDVal == "b") {
2144 getContext().getDirectionalLocalSymbol(IntVal, IDVal == "b");
2146 const MCExpr *Val =
2149 return Error(Loc, "invalid reference to undefined symbol");
2151 InlineAsmIdentifierInfo Info;
2152 AsmTypeInfo Type;
2153 if (SM.onIdentifierExpr(Val, Identifier, Info, Type,
2154 isParsingMSInlineAsm(), ErrMsg))
2155 return Error(Loc, ErrMsg);
2156 End = consumeToken();
2157 } else {
2158 if (SM.onInteger(IntVal, ErrMsg))
2159 return Error(Loc, ErrMsg);
2160 }
2161 } else {
2162 if (SM.onInteger(IntVal, ErrMsg))
2163 return Error(Loc, ErrMsg);
2164 }
2165 break;
2166 }
2168 if (SM.onPlus(ErrMsg))
2169 return Error(getTok().getLoc(), ErrMsg);
2170 break;
2172 if (SM.onMinus(ErrMsg))
2173 return Error(getTok().getLoc(), ErrMsg);
2174 break;
2183 SM.onLShift(); break;
2185 SM.onRShift(); break;
2187 if (SM.onLBrac())
2188 return Error(Tok.getLoc(), "unexpected bracket encountered");
2189 tryParseOperandIdx(PrevTK, SM);
2190 break;
2192 if (SM.onRBrac(ErrMsg)) {
2194 }
2195 break;
2198 if (SM.onRParen(ErrMsg)) {
2200 }
2201 break;
2202 }
2203 if (SM.hadError())
2204 return Error(Tok.getLoc(), "unknown token in expression");
2205
2206 if ( && UpdateLocLex)
2207 End = consumeToken();
2208
2209 PrevTK = TK;
2210 }
2211 return false;
2212}
2213
2214void X86AsmParser::RewriteIntelExpression(IntelExprStateMachine &SM,
2215 SMLoc Start, SMLoc End) {
2216 SMLoc Loc = Start;
2217 unsigned ExprLen = End.getPointer() - Start.getPointer();
2218
2219 if (SM.getSym() && !SM.isOffsetOperator()) {
2220 StringRef SymName = SM.getSymName();
2221 if (unsigned Len = SymName.data() - Start.getPointer())
2225
2226
2227 if (!(SM.getBaseReg() || SM.getIndexReg() || SM.getImm())) {
2228 if (ExprLen)
2230 return;
2231 }
2232 }
2233
2234 StringRef BaseRegStr;
2235 StringRef IndexRegStr;
2236 StringRef OffsetNameStr;
2237 if (SM.getBaseReg())
2239 if (SM.getIndexReg())
2241 if (SM.isOffsetOperator())
2242 OffsetNameStr = SM.getSymName();
2243
2244 IntelExpr Expr(BaseRegStr, IndexRegStr, SM.getScale(), OffsetNameStr,
2245 SM.getImm(), SM.isMemExpr());
2246 InstInfo->AsmRewrites->emplace_back(Loc, ExprLen, Expr);
2247}
2248
2249
2250bool X86AsmParser::ParseIntelInlineAsmIdentifier(
2251 const MCExpr *&Val, StringRef &Identifier, InlineAsmIdentifierInfo &Info,
2252 bool IsUnevaluatedOperand, SMLoc &End, bool IsParsingOffsetOperator) {
2253 MCAsmParser &Parser = getParser();
2254 assert(isParsingMSInlineAsm() && "Expected to be parsing inline assembly.");
2255 Val = nullptr;
2256
2257 StringRef LineBuf(Identifier.data());
2258 SemaCallback->LookupInlineAsmIdentifier(LineBuf, Info, IsUnevaluatedOperand);
2259
2260 const AsmToken &Tok = Parser.getTok();
2261 SMLoc Loc = Tok.getLoc();
2262
2263
2264
2265 const char *EndPtr = Tok.getLoc().getPointer() + LineBuf.size();
2266 do {
2268 getLexer().Lex();
2269 } while (End.getPointer() < EndPtr);
2271
2272
2273
2276 "frontend claimed part of a token?");
2277
2278
2279
2281 StringRef InternalName =
2282 SemaCallback->LookupInlineAsmLabel(Identifier, getSourceManager(),
2283 Loc, false);
2284 assert(InternalName.size() && "We should have an internal name here.");
2285
2286
2287 if (!IsParsingOffsetOperator)
2289 InternalName);
2290 else
2293 return false;
2294
2298 return false;
2299}
2300
2301
2302bool X86AsmParser::ParseRoundingModeOp(SMLoc Start, OperandVector &Operands) {
2303 MCAsmParser &Parser = getParser();
2304 const AsmToken &Tok = Parser.getTok();
2305
2306 const SMLoc consumedToken = consumeToken();
2308 return Error(Tok.getLoc(), "Expected an identifier after {");
2310 int rndMode = StringSwitch(Tok.getIdentifier())
2311 .Case("rn", X86::STATIC_ROUNDING::TO_NEAREST_INT)
2312 .Case("rd", X86::STATIC_ROUNDING::TO_NEG_INF)
2313 .Case("ru", X86::STATIC_ROUNDING::TO_POS_INF)
2314 .Case("rz", X86::STATIC_ROUNDING::TO_ZERO)
2315 .Default(-1);
2316 if (-1 == rndMode)
2317 return Error(Tok.getLoc(), "Invalid rounding mode.");
2318 Parser.Lex();
2320 return Error(Tok.getLoc(), "Expected - at this point");
2321 Parser.Lex();
2322 Parser.Lex();
2324 return Error(Tok.getLoc(), "Expected } at this point");
2326 Parser.Lex();
2327 const MCExpr *RndModeOp =
2330 return false;
2331 }
2333 Parser.Lex();
2335 return Error(Tok.getLoc(), "Expected } at this point");
2336 Parser.Lex();
2338 return false;
2339 }
2340 return Error(Tok.getLoc(), "unknown token in expression");
2341}
2342
2343
2344
2345bool X86AsmParser::parseCFlagsOp(OperandVector &Operands) {
2346 MCAsmParser &Parser = getParser();
2347 AsmToken Tok = Parser.getTok();
2350 return Error(Tok.getLoc(), "Expected { at this point");
2351 Parser.Lex();
2352 Tok = Parser.getTok();
2354 return Error(Tok.getLoc(), "Expected dfv at this point");
2355 Parser.Lex();
2356 Tok = Parser.getTok();
2358 return Error(Tok.getLoc(), "Expected = at this point");
2359 Parser.Lex();
2360
2361 Tok = Parser.getTok();
2362 SMLoc End;
2367 Parser.Lex();
2368 return false;
2369 }
2370 unsigned CFlags = 0;
2371 for (unsigned I = 0; I < 4; ++I) {
2372 Tok = Parser.getTok();
2373 unsigned CFlag = StringSwitch(Tok.getIdentifier().lower())
2374 .Case("of", 0x8)
2375 .Case("sf", 0x4)
2376 .Case("zf", 0x2)
2377 .Case("cf", 0x1)
2378 .Default(~0U);
2379 if (CFlag == ~0U)
2380 return Error(Tok.getLoc(), "Invalid conditional flags");
2381
2382 if (CFlags & CFlag)
2383 return Error(Tok.getLoc(), "Duplicated conditional flag");
2384 CFlags |= CFlag;
2385
2386 Parser.Lex();
2387 Tok = Parser.getTok();
2392 Parser.Lex();
2393 return false;
2394 } else if (I == 3) {
2395 return Error(Tok.getLoc(), "Expected } at this point");
2397 return Error(Tok.getLoc(), "Expected } or , at this point");
2398 }
2399 Parser.Lex();
2400 }
2402}
2403
2404
2405bool X86AsmParser::ParseIntelDotOperator(IntelExprStateMachine &SM,
2406 SMLoc &End) {
2407 const AsmToken &Tok = getTok();
2408 AsmFieldInfo Info;
2409
2410
2411 StringRef DotDispStr = Tok.getString();
2413 bool TrailingDot = false;
2414
2415
2417 APInt DotDisp;
2419 return Error(Tok.getLoc(), "Unexpected offset");
2421 } else if ((isParsingMSInlineAsm() || getParser().isParsingMasm()) &&
2424 const std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
2425 const StringRef Base = BaseMember.first, Member = BaseMember.second;
2426 if (getParser().lookUpField(SM.getType(), DotDispStr, Info) &&
2427 getParser().lookUpField(SM.getSymName(), DotDispStr, Info) &&
2428 getParser().lookUpField(DotDispStr, Info) &&
2429 (!SemaCallback ||
2430 SemaCallback->LookupInlineAsmField(Base, Member, Info.Offset)))
2431 return Error(Tok.getLoc(), "Unable to lookup field reference!");
2432 } else {
2433 return Error(Tok.getLoc(), "Unexpected token type!");
2434 }
2435
2436
2438 const char *DotExprEndLoc = DotDispStr.data() + DotDispStr.size();
2440 Lex();
2441 if (TrailingDot)
2443 SM.addImm(Info.Offset);
2444 SM.setTypeInfo(Info.Type);
2445 return false;
2446}
2447
2448
2449
2450bool X86AsmParser::ParseIntelOffsetOperator(const MCExpr *&Val, StringRef &ID,
2451 InlineAsmIdentifierInfo &Info,
2452 SMLoc &End) {
2453
2454 SMLoc Start = Lex().getLoc();
2455 ID = getTok().getString();
2456 if (!isParsingMSInlineAsm()) {
2459 getParser().parsePrimaryExpr(Val, End, nullptr))
2460 return Error(Start, "unexpected token!");
2461 } else if (ParseIntelInlineAsmIdentifier(Val, ID, Info, false, End, true)) {
2462 return Error(Start, "unable to lookup expression");
2464 return Error(Start, "offset operator cannot yet handle constants");
2465 }
2466 return false;
2467}
2468
2469
2470
2471unsigned X86AsmParser::IdentifyIntelInlineAsmOperator(StringRef Name) {
2472 return StringSwitch(Name)
2473 .Cases({"TYPE", "type"}, IOK_TYPE)
2474 .Cases({"SIZE", "size"}, IOK_SIZE)
2475 .Cases({"LENGTH", "length"}, IOK_LENGTH)
2477}
2478
2479
2480
2481
2482
2483
2484
2485unsigned X86AsmParser::ParseIntelInlineAsmOperator(unsigned OpKind) {
2486 MCAsmParser &Parser = getParser();
2487 const AsmToken &Tok = Parser.getTok();
2488 Parser.Lex();
2489
2490 const MCExpr *Val = nullptr;
2491 InlineAsmIdentifierInfo Info;
2494 if (ParseIntelInlineAsmIdentifier(Val, Identifier, Info,
2495 true, End))
2496 return 0;
2497
2499 Error(Start, "unable to lookup expression");
2500 return 0;
2501 }
2502
2503 unsigned CVal = 0;
2504 switch(OpKind) {
2506 case IOK_LENGTH: CVal = Info.Var.Length; break;
2507 case IOK_SIZE: CVal = Info.Var.Size; break;
2508 case IOK_TYPE: CVal = Info.Var.Type; break;
2509 }
2510
2511 return CVal;
2512}
2513
2514
2515
2516unsigned X86AsmParser::IdentifyMasmOperator(StringRef Name) {
2517 return StringSwitch(Name.lower())
2518 .Case("type", MOK_TYPE)
2519 .Cases({"size", "sizeof"}, MOK_SIZEOF)
2520 .Cases({"length", "lengthof"}, MOK_LENGTHOF)
2522}
2523
2524
2525
2526
2527
2528
2529
2530bool X86AsmParser::ParseMasmOperator(unsigned OpKind, int64_t &Val) {
2531 MCAsmParser &Parser = getParser();
2533 Parser.Lex();
2534
2535 Val = 0;
2536 if (OpKind == MOK_SIZEOF || OpKind == MOK_TYPE) {
2537
2539 const AsmToken &IDTok = InParens ? getLexer().peekTok() : Parser.getTok();
2540 AsmTypeInfo Type;
2543 Val = Type.Size;
2544
2545
2546 if (InParens)
2549 if (InParens)
2551 }
2552 }
2553
2554 if (!Val) {
2555 IntelExprStateMachine SM;
2557 if (ParseIntelExpression(SM, End))
2558 return true;
2559
2560 switch (OpKind) {
2561 default:
2563 case MOK_SIZEOF:
2564 Val = SM.getSize();
2565 break;
2566 case MOK_LENGTHOF:
2567 Val = SM.getLength();
2568 break;
2569 case MOK_TYPE:
2570 Val = SM.getElementSize();
2571 break;
2572 }
2573
2574 if (!Val)
2575 return Error(OpLoc, "expression has unknown type", SMRange(Start, End));
2576 }
2577
2578 return false;
2579}
2580
2581bool X86AsmParser::ParseIntelMemoryOperandSize(unsigned &Size,
2582 StringRef *SizeStr) {
2583 Size = StringSwitch(getTok().getString())
2584 .Cases({"BYTE", "byte"}, 8)
2585 .Cases({"WORD", "word"}, 16)
2586 .Cases({"DWORD", "dword"}, 32)
2587 .Cases({"FLOAT", "float"}, 32)
2588 .Cases({"LONG", "long"}, 32)
2589 .Cases({"FWORD", "fword"}, 48)
2590 .Cases({"DOUBLE", "double"}, 64)
2591 .Cases({"QWORD", "qword"}, 64)
2592 .Cases({"MMWORD", "mmword"}, 64)
2593 .Cases({"XWORD", "xword"}, 80)
2594 .Cases({"TBYTE", "tbyte"}, 80)
2595 .Cases({"XMMWORD", "xmmword"}, 128)
2596 .Cases({"YMMWORD", "ymmword"}, 256)
2597 .Cases({"ZMMWORD", "zmmword"}, 512)
2600 if (SizeStr)
2601 *SizeStr = getTok().getString();
2602 const AsmToken &Tok = Lex();
2604 return Error(Tok.getLoc(), "Expected 'PTR' or 'ptr' token!");
2605 Lex();
2606 }
2607 return false;
2608}
2609
2611 if (X86MCRegisterClasses[X86::GR8RegClassID].contains(RegNo))
2612 return 8;
2613 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(RegNo))
2614 return 16;
2615 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(RegNo))
2616 return 32;
2617 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
2618 return 64;
2619
2620 return 0;
2621}
2622
2623bool X86AsmParser::parseIntelOperand(OperandVector &Operands, StringRef Name) {
2624 MCAsmParser &Parser = getParser();
2625 const AsmToken &Tok = Parser.getTok();
2626 SMLoc Start, End;
2627
2628
2629 unsigned Size;
2630 StringRef SizeStr;
2631 if (ParseIntelMemoryOperandSize(Size, &SizeStr))
2632 return true;
2633 bool PtrInOperand = bool(Size);
2634
2636
2637
2639 return ParseRoundingModeOp(Start, Operands);
2640
2641
2642 MCRegister RegNo;
2644 if (RegNo == X86::RIP)
2645 return Error(Start, "rip can only be used as a base register");
2646
2648 if (PtrInOperand) {
2650 return Error(Start, "expected memory operand after 'ptr', "
2651 "found register operand instead");
2652
2653
2654
2659 Start,
2660 "cannot cast register '" +
2662 "'; its size is not easily defined.");
2665 Start,
2666 std::to_string(RegSize) + "-bit register '" +
2668 "' cannot be used as a " + std::to_string(Size) + "-bit " +
2669 SizeStr.upper());
2670 }
2672 return false;
2673 }
2674
2675 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(RegNo))
2676 return Error(Start, "invalid segment register");
2677
2678 Start = Lex().getLoc();
2679 }
2680
2681
2682 IntelExprStateMachine SM;
2683 if (ParseIntelExpression(SM, End))
2684 return true;
2685
2686 if (isParsingMSInlineAsm())
2687 RewriteIntelExpression(SM, Start, Tok.getLoc());
2688
2689 int64_t Imm = SM.getImm();
2690 const MCExpr *Disp = SM.getSym();
2692 if (Disp && Imm)
2694 if (!Disp)
2695 Disp = ImmDisp;
2696
2697
2698
2699 if (!SM.isMemExpr() && !RegNo) {
2700 if (isParsingMSInlineAsm() && SM.isOffsetOperator()) {
2701 const InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
2703
2704
2706 SM.getSymName(), Info.Var.Decl,
2707 Info.Var.IsGlobalLV));
2708 return false;
2709 }
2710 }
2711
2713 return false;
2714 }
2715
2716 StringRef ErrMsg;
2717 MCRegister BaseReg = SM.getBaseReg();
2718 MCRegister IndexReg = SM.getIndexReg();
2719 if (IndexReg && BaseReg == X86::RIP)
2721 unsigned Scale = SM.getScale();
2722 if (!PtrInOperand)
2723 Size = SM.getElementSize() << 3;
2724
2725 if (Scale == 0 && BaseReg != X86::ESP && BaseReg != X86::RSP &&
2726 (IndexReg == X86::ESP || IndexReg == X86::RSP))
2728
2729
2730
2731 if (Scale == 0 &&
2732 !(X86MCRegisterClasses[X86::VR128XRegClassID].contains(IndexReg) ||
2733 X86MCRegisterClasses[X86::VR256XRegClassID].contains(IndexReg) ||
2734 X86MCRegisterClasses[X86::VR512RegClassID].contains(IndexReg)) &&
2735 (X86MCRegisterClasses[X86::VR128XRegClassID].contains(BaseReg) ||
2736 X86MCRegisterClasses[X86::VR256XRegClassID].contains(BaseReg) ||
2737 X86MCRegisterClasses[X86::VR512RegClassID].contains(BaseReg)))
2739
2740 if (Scale != 0 &&
2741 X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg))
2742 return Error(Start, "16-bit addresses cannot have a scale");
2743
2744
2745 if (Scale == 0)
2746 Scale = 1;
2747
2748
2749
2750
2751 if ((BaseReg == X86::SI || BaseReg == X86::DI) &&
2752 (IndexReg == X86::BX || IndexReg == X86::BP))
2754
2755 if ((BaseReg || IndexReg) &&
2757 ErrMsg))
2758 return Error(Start, ErrMsg);
2759 bool IsUnconditionalBranch =
2760 Name.equals_insensitive("jmp") || Name.equals_insensitive("call");
2761 if (isParsingMSInlineAsm())
2762 return CreateMemForMSInlineAsm(RegNo, Disp, BaseReg, IndexReg, Scale,
2763 IsUnconditionalBranch && is64BitMode(),
2764 Start, End, Size, SM.getSymName(),
2765 SM.getIdentifierInfo(), Operands);
2766
2767
2768
2769 MCRegister DefaultBaseReg;
2770 bool MaybeDirectBranchDest = true;
2771
2773 if (is64BitMode() &&
2774 ((PtrInOperand && !IndexReg) || SM.getElementSize() > 0)) {
2775 DefaultBaseReg = X86::RIP;
2776 }
2777 if (IsUnconditionalBranch) {
2778 if (PtrInOperand) {
2779 MaybeDirectBranchDest = false;
2780 if (is64BitMode())
2781 DefaultBaseReg = X86::RIP;
2782 } else if (!BaseReg && !IndexReg && Disp &&
2784 if (is64BitMode()) {
2785 if (SM.getSize() == 8) {
2786 MaybeDirectBranchDest = false;
2787 DefaultBaseReg = X86::RIP;
2788 }
2789 } else {
2790 if (SM.getSize() == 4 || SM.getSize() == 2)
2791 MaybeDirectBranchDest = false;
2792 }
2793 }
2794 }
2795 } else if (IsUnconditionalBranch) {
2796
2797 if (!PtrInOperand && SM.isOffsetOperator())
2799 Start, "`OFFSET` operator cannot be used in an unconditional branch");
2800 if (PtrInOperand || SM.isBracketUsed())
2801 MaybeDirectBranchDest = false;
2802 }
2803
2804 if ((BaseReg || IndexReg || RegNo || DefaultBaseReg))
2806 getPointerWidth(), RegNo, Disp, BaseReg, IndexReg, Scale, Start, End,
2807 Size, DefaultBaseReg, StringRef(), nullptr,
2808 0, false, MaybeDirectBranchDest));
2809 else
2811 getPointerWidth(), Disp, Start, End, Size, StringRef(),
2812 nullptr, 0, false,
2813 MaybeDirectBranchDest));
2814 return false;
2815}
2816
2817bool X86AsmParser::parseATTOperand(OperandVector &Operands) {
2818 MCAsmParser &Parser = getParser();
2819 switch (getLexer().getKind()) {
2821
2823 Parser.Lex();
2824 const MCExpr *Val;
2825
2826
2829 "expected immediate expression") ||
2830 getParser().parseExpression(Val, End) ||
2831 check(isa(Val), L, "expected immediate expression"))
2832 return true;
2834 return false;
2835 }
2838 return ParseRoundingModeOp(Start, Operands);
2839 }
2840 default: {
2841
2842
2843
2844
2845
2846 SMLoc Loc = Parser.getTok().getLoc(), EndLoc;
2847 const MCExpr *Expr = nullptr;
2848 MCRegister Reg;
2850
2852 return true;
2854
2855 Expr = nullptr;
2856 Reg = RE->getReg();
2857
2858
2859 if (Reg == X86::EIZ || Reg == X86::RIZ)
2861 Loc, "%eiz and %riz can only be used as index registers",
2862 SMRange(Loc, EndLoc));
2863 if (Reg == X86::RIP)
2864 return Error(Loc, "%rip can only be used as a base register",
2865 SMRange(Loc, EndLoc));
2866
2869 return false;
2870 }
2871 if (!X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(Reg))
2872 return Error(Loc, "invalid segment register");
2873
2874
2877 }
2878 }
2879
2880 return ParseMemOperand(Reg, Expr, Loc, EndLoc, Operands);
2881 }
2882 }
2883}
2884
2885
2886
2887X86::CondCode X86AsmParser::ParseConditionCode(StringRef CC) {
2888 return StringSwitchX86::CondCode(CC)
2891 .Cases({"b", "nae"}, X86::COND_B)
2892 .Cases({"ae", "nb"}, X86::COND_AE)
2893 .Cases({"e", "z"}, X86::COND_E)
2894 .Cases({"ne", "nz"}, X86::COND_NE)
2895 .Cases({"be", "na"}, X86::COND_BE)
2896 .Cases({"a", "nbe"}, X86::COND_A)
2899 .Cases({"p", "pe"}, X86::COND_P)
2900 .Cases({"np", "po"}, X86::COND_NP)
2901 .Cases({"l", "nge"}, X86::COND_L)
2902 .Cases({"ge", "nl"}, X86::COND_GE)
2903 .Cases({"le", "ng"}, X86::COND_LE)
2904 .Cases({"g", "nle"}, X86::COND_G)
2906}
2907
2908
2909
2910bool X86AsmParser::ParseZ(std::unique_ptr &Z, SMLoc StartLoc) {
2911 MCAsmParser &Parser = getParser();
2912
2913
2914
2916 (getLexer().getTok().getIdentifier() == "z")))
2917 return false;
2918 Parser.Lex();
2919
2921 return Error(getLexer().getLoc(), "Expected } at this point");
2922 Parser.Lex();
2923
2925 return false;
2926}
2927
2928
2929bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands) {
2930 MCAsmParser &Parser = getParser();
2932
2933 const SMLoc consumedToken = consumeToken();
2934
2936
2937 if (getLexer().getTok().getIntVal() != 1)
2938 return TokError("Expected 1to at this point");
2939 StringRef Prefix = getLexer().getTok().getString();
2940 Parser.Lex();
2942 return TokError("Expected 1to at this point");
2943
2945 StringRef BroadcastString = (Prefix + getLexer().getTok().getIdentifier())
2947 if (!BroadcastString.starts_with("1to"))
2948 return TokError("Expected 1to at this point");
2949 const char *BroadcastPrimitive =
2950 StringSwitch<const char *>(BroadcastString)
2951 .Case("1to2", "{1to2}")
2952 .Case("1to4", "{1to4}")
2953 .Case("1to8", "{1to8}")
2954 .Case("1to16", "{1to16}")
2955 .Case("1to32", "{1to32}")
2956 .Default(nullptr);
2957 if (!BroadcastPrimitive)
2958 return TokError("Invalid memory broadcast primitive.");
2959 Parser.Lex();
2961 return TokError("Expected } at this point");
2962 Parser.Lex();
2964 consumedToken));
2965
2966
2967 return false;
2968 } else {
2969
2970
2971
2972 std::unique_ptr Z;
2973 if (ParseZ(Z, consumedToken))
2974 return true;
2975
2976
2977
2979 SMLoc StartLoc = Z ? consumeToken() : consumedToken;
2980
2981
2982 MCRegister RegNo;
2983 SMLoc RegLoc;
2984 if (!parseRegister(RegNo, RegLoc, StartLoc) &&
2985 X86MCRegisterClasses[X86::VK1RegClassID].contains(RegNo)) {
2986 if (RegNo == X86::K0)
2987 return Error(RegLoc, "Register k0 can't be used as write mask");
2989 return Error(getLexer().getLoc(), "Expected } at this point");
2994 } else
2995 return Error(getLexer().getLoc(),
2996 "Expected an op-mask register at this point");
2997
2999
3000
3001 if (ParseZ(Z, consumeToken()) || !Z)
3002 return Error(getLexer().getLoc(),
3003 "Expected a {z} mark at this point");
3004
3005 }
3006
3007
3008
3009 if (Z)
3010 Operands.push_back(std::move(Z));
3011 }
3012 }
3013 }
3014 return false;
3015}
3016
3017
3018
3019bool X86AsmParser::ParseMemOperand(MCRegister SegReg, const MCExpr *Disp,
3020 SMLoc StartLoc, SMLoc EndLoc,
3022 MCAsmParser &Parser = getParser();
3023 SMLoc Loc;
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040 auto isAtMemOperand = [this]() {
3042 return false;
3043 AsmToken Buf[2];
3044 StringRef Id;
3045 auto TokCount = this->getLexer().peekTokens(Buf, true);
3046 if (TokCount == 0)
3047 return false;
3048 switch (Buf[0].getKind()) {
3051 return true;
3052
3055 if ((TokCount > 1) &&
3058 Id = StringRef(Buf[0].getLoc().getPointer(),
3059 Buf[1].getIdentifier().size() + 1);
3060 break;
3064 break;
3065 default:
3066 return false;
3067 }
3068
3069 if (.empty()) {
3074 }
3075 }
3076 return false;
3077 };
3078
3079 if (!Disp) {
3080
3081 if (!isAtMemOperand()) {
3083 return true;
3085 } else {
3086
3088 }
3089 }
3090
3091
3092
3093
3095 if (!SegReg)
3098 else
3100 0, 0, 1, StartLoc, EndLoc));
3101 return false;
3102 }
3103
3104
3105
3106 MCRegister BaseReg, IndexReg;
3107 unsigned Scale = 1;
3108 SMLoc BaseLoc = getLexer().getLoc();
3109 const MCExpr *E;
3110 StringRef ErrMsg;
3111
3112
3115 check((E), BaseLoc, "expected register here"))
3116 return true;
3117
3118
3120 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ)
3121 return Error(BaseLoc, "eiz and riz can only be used as index registers",
3122 SMRange(BaseLoc, EndLoc));
3123 }
3124
3126
3127
3128
3129
3130
3131
3134 return true;
3135
3137
3138
3139 int64_t ScaleVal;
3140 if (->evaluateAsAbsolute(ScaleVal, getStreamer().getAssemblerPtr()))
3141 return Error(Loc, "expected absolute expression");
3142 if (ScaleVal != 1)
3143 Warning(Loc, "scale factor without index register is ignored");
3144 Scale = 1;
3145 } else {
3147
3148 if (BaseReg == X86::RIP)
3149 return Error(Loc,
3150 "%rip as base register can not have an index register");
3151 if (IndexReg == X86::RIP)
3152 return Error(Loc, "%rip is not allowed as an index register");
3153
3155
3156
3157
3158
3160 int64_t ScaleVal;
3163 return Error(Loc, "expected scale expression");
3164 Scale = (unsigned)ScaleVal;
3165
3166 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) &&
3167 Scale != 1)
3168 return Error(Loc, "scale factor in 16-bit address must be 1");
3170 return Error(Loc, ErrMsg);
3171 }
3172 }
3173 }
3174 }
3175 }
3176
3177
3178 if (parseToken(AsmToken::RParen, "unexpected token in memory operand"))
3179 return true;
3180
3181
3182
3183
3184 if (BaseReg == X86::DX && !IndexReg && Scale == 1 && !SegReg &&
3188 return false;
3189 }
3190
3192 ErrMsg))
3193 return Error(BaseLoc, ErrMsg);
3194
3195
3196
3197
3198
3199
3200 if (BaseReg || IndexReg) {
3202 auto Imm = CE->getValue();
3203 bool Is64 = X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) ||
3204 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg);
3205 bool Is16 = X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg);
3206 if (Is64) {
3208 return Error(BaseLoc, "displacement " + Twine(Imm) +
3209 " is not within [-2147483648, 2147483647]");
3210 } else if (!Is16) {
3211 if ((Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
3212 Warning(BaseLoc, "displacement " + Twine(Imm) +
3213 " shortened to 32-bit signed " +
3214 Twine(static_cast<int32_t>(Imm)));
3215 }
3216 } else if ((Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
3217 Warning(BaseLoc, "displacement " + Twine(Imm) +
3218 " shortened to 16-bit signed " +
3219 Twine(static_cast<int16_t>(Imm)));
3220 }
3221 }
3222 }
3223
3224 if (SegReg || BaseReg || IndexReg)
3226 BaseReg, IndexReg, Scale, StartLoc,
3227 EndLoc));
3228 else
3231 return false;
3232}
3233
3234
3235bool X86AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
3236 MCAsmParser &Parser = getParser();
3237
3242 MCRegister RegNo;
3243 if (parseRegister(RegNo, StartLoc, EndLoc))
3244 return true;
3246 return false;
3247 }
3249}
3250
3251bool X86AsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
3253 MCAsmParser &Parser = getParser();
3254 InstInfo = &Info;
3255
3256
3257 ForcedOpcodePrefix = OpcodePrefix_Default;
3258 ForcedDispEncoding = DispEncoding_Default;
3259 UseApxExtendedReg = false;
3260 ForcedNoFlag = false;
3261
3262
3263 while (true) {
3264 if (Name == "{") {
3266 return Error(Parser.getTok().getLoc(), "Unexpected token after '{'");
3268 Parser.Lex();
3271 Parser.Lex();
3272
3273 if (Prefix == "rex")
3274 ForcedOpcodePrefix = OpcodePrefix_REX;
3275 else if (Prefix == "rex2")
3276 ForcedOpcodePrefix = OpcodePrefix_REX2;
3277 else if (Prefix == "vex")
3278 ForcedOpcodePrefix = OpcodePrefix_VEX;
3279 else if (Prefix == "vex2")
3280 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3281 else if (Prefix == "vex3")
3282 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3283 else if (Prefix == "evex")
3284 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3285 else if (Prefix == "disp8")
3286 ForcedDispEncoding = DispEncoding_Disp8;
3287 else if (Prefix == "disp32")
3288 ForcedDispEncoding = DispEncoding_Disp32;
3289 else if (Prefix == "nf")
3290 ForcedNoFlag = true;
3291 else
3292 return Error(NameLoc, "unknown prefix");
3293
3296 Parser.Lex();
3298 } else {
3301
3303 Parser.Lex();
3304 }
3305 continue;
3306 }
3307
3308 if (isParsingMSInlineAsm()) {
3309 if (Name.equals_insensitive("vex"))
3310 ForcedOpcodePrefix = OpcodePrefix_VEX;
3311 else if (Name.equals_insensitive("vex2"))
3312 ForcedOpcodePrefix = OpcodePrefix_VEX2;
3313 else if (Name.equals_insensitive("vex3"))
3314 ForcedOpcodePrefix = OpcodePrefix_VEX3;
3315 else if (Name.equals_insensitive("evex"))
3316 ForcedOpcodePrefix = OpcodePrefix_EVEX;
3317
3318 if (ForcedOpcodePrefix != OpcodePrefix_Default) {
3321
3324 Parser.Lex();
3325 }
3326 }
3327 break;
3328 }
3329
3330
3331 if (Name.consume_back(".d32")) {
3332 ForcedDispEncoding = DispEncoding_Disp32;
3333 } else if (Name.consume_back(".d8")) {
3334 ForcedDispEncoding = DispEncoding_Disp8;
3335 }
3336
3337 StringRef PatchedName = Name;
3338
3339
3340 if (isParsingIntelSyntax() &&
3341 (PatchedName == "jmp" || PatchedName == "jc" || PatchedName == "jnc" ||
3342 PatchedName == "jcxz" || PatchedName == "jecxz" ||
3347 : NextTok == "short") {
3348 SMLoc NameEndLoc =
3350
3351 Parser.Lex();
3352
3353
3354
3356 NextTok.size() + 1);
3357 }
3358 }
3359
3360
3362 PatchedName != "setzub" && PatchedName != "setzunb" &&
3363 PatchedName != "setb" && PatchedName != "setnb")
3364 PatchedName = PatchedName.substr(0, Name.size()-1);
3365
3366 unsigned ComparisonPredicate = ~0U;
3367
3368
3374 bool IsVCMP = PatchedName[0] == 'v';
3375 unsigned CCIdx = IsVCMP ? 4 : 3;
3376 unsigned suffixLength = PatchedName.ends_with("bf16") ? 5 : 2;
3377 unsigned CC = StringSwitch(
3378 PatchedName.slice(CCIdx, PatchedName.size() - suffixLength))
3379 .Case("eq", 0x00)
3380 .Case("eq_oq", 0x00)
3381 .Case("lt", 0x01)
3382 .Case("lt_os", 0x01)
3383 .Case("le", 0x02)
3384 .Case("le_os", 0x02)
3385 .Case("unord", 0x03)
3386 .Case("unord_q", 0x03)
3387 .Case("neq", 0x04)
3388 .Case("neq_uq", 0x04)
3389 .Case("nlt", 0x05)
3390 .Case("nlt_us", 0x05)
3391 .Case("nle", 0x06)
3392 .Case("nle_us", 0x06)
3393 .Case("ord", 0x07)
3394 .Case("ord_q", 0x07)
3395
3396 .Case("eq_uq", 0x08)
3397 .Case("nge", 0x09)
3398 .Case("nge_us", 0x09)
3399 .Case("ngt", 0x0A)
3400 .Case("ngt_us", 0x0A)
3401 .Case("false", 0x0B)
3402 .Case("false_oq", 0x0B)
3403 .Case("neq_oq", 0x0C)
3404 .Case("ge", 0x0D)
3405 .Case("ge_os", 0x0D)
3406 .Case("gt", 0x0E)
3407 .Case("gt_os", 0x0E)
3408 .Case("true", 0x0F)
3409 .Case("true_uq", 0x0F)
3410 .Case("eq_os", 0x10)
3411 .Case("lt_oq", 0x11)
3412 .Case("le_oq", 0x12)
3413 .Case("unord_s", 0x13)
3414 .Case("neq_us", 0x14)
3415 .Case("nlt_uq", 0x15)
3416 .Case("nle_uq", 0x16)
3417 .Case("ord_s", 0x17)
3418 .Case("eq_us", 0x18)
3419 .Case("nge_uq", 0x19)
3420 .Case("ngt_uq", 0x1A)
3421 .Case("false_os", 0x1B)
3422 .Case("neq_os", 0x1C)
3423 .Case("ge_oq", 0x1D)
3424 .Case("gt_oq", 0x1E)
3425 .Case("true_us", 0x1F)
3426 .Default(~0U);
3427 if (CC != ~0U && (IsVCMP || CC < 8) &&
3428 (IsVCMP || PatchedName.back() != 'h')) {
3429 if (PatchedName.ends_with("ss"))
3430 PatchedName = IsVCMP ? "vcmpss" : "cmpss";
3431 else if (PatchedName.ends_with("sd"))
3432 PatchedName = IsVCMP ? "vcmpsd" : "cmpsd";
3433 else if (PatchedName.ends_with("ps"))
3434 PatchedName = IsVCMP ? "vcmpps" : "cmpps";
3435 else if (PatchedName.ends_with("pd"))
3436 PatchedName = IsVCMP ? "vcmppd" : "cmppd";
3437 else if (PatchedName.ends_with("sh"))
3438 PatchedName = "vcmpsh";
3439 else if (PatchedName.ends_with("ph"))
3440 PatchedName = "vcmpph";
3441 else if (PatchedName.ends_with("bf16"))
3442 PatchedName = "vcmpbf16";
3443 else
3445
3446 ComparisonPredicate = CC;
3447 }
3448 }
3449
3450
3452 (PatchedName.back() == 'b' || PatchedName.back() == 'w' ||
3453 PatchedName.back() == 'd' || PatchedName.back() == 'q')) {
3454 unsigned SuffixSize = PatchedName.drop_back().back() == 'u' ? 2 : 1;
3455 unsigned CC = StringSwitch(
3456 PatchedName.slice(5, PatchedName.size() - SuffixSize))
3457 .Case("eq", 0x0)
3458 .Case("lt", 0x1)
3459 .Case("le", 0x2)
3460
3461 .Case("neq", 0x4)
3462 .Case("nlt", 0x5)
3463 .Case("nle", 0x6)
3464
3465 .Default(~0U);
3466 if (CC != ~0U && (CC != 0 || SuffixSize == 2)) {
3467 switch (PatchedName.back()) {
3469 case 'b': PatchedName = SuffixSize == 2 ? "vpcmpub" : "vpcmpb"; break;
3470 case 'w': PatchedName = SuffixSize == 2 ? "vpcmpuw" : "vpcmpw"; break;
3471 case 'd': PatchedName = SuffixSize == 2 ? "vpcmpud" : "vpcmpd"; break;
3472 case 'q': PatchedName = SuffixSize == 2 ? "vpcmpuq" : "vpcmpq"; break;
3473 }
3474
3475 ComparisonPredicate = CC;
3476 }
3477 }
3478
3479
3481 (PatchedName.back() == 'b' || PatchedName.back() == 'w' ||
3482 PatchedName.back() == 'd' || PatchedName.back() == 'q')) {
3483 unsigned SuffixSize = PatchedName.drop_back().back() == 'u' ? 2 : 1;
3484 unsigned CC = StringSwitch(
3485 PatchedName.slice(5, PatchedName.size() - SuffixSize))
3486 .Case("lt", 0x0)
3487 .Case("le", 0x1)
3488 .Case("gt", 0x2)
3489 .Case("ge", 0x3)
3490 .Case("eq", 0x4)
3491 .Case("neq", 0x5)
3492 .Case("false", 0x6)
3493 .Case("true", 0x7)
3494 .Default(~0U);
3495 if (CC != ~0U) {
3496 switch (PatchedName.back()) {
3498 case 'b': PatchedName = SuffixSize == 2 ? "vpcomub" : "vpcomb"; break;
3499 case 'w': PatchedName = SuffixSize == 2 ? "vpcomuw" : "vpcomw"; break;
3500 case 'd': PatchedName = SuffixSize == 2 ? "vpcomud" : "vpcomd"; break;
3501 case 'q': PatchedName = SuffixSize == 2 ? "vpcomuq" : "vpcomq"; break;
3502 }
3503
3504 ComparisonPredicate = CC;
3505 }
3506 }
3507
3508
3509
3510
3511
3512
3513
3514
3515 bool IsPrefix =
3516 StringSwitch(Name)
3517 .Cases({"cs", "ds", "es", "fs", "gs", "ss"}, true)
3518 .Cases({"rex64", "data32", "data16", "addr32", "addr16"}, true)
3519 .Cases({"xacquire", "xrelease"}, true)
3520 .Cases({"acquire", "release"}, isParsingIntelSyntax())
3522
3523 auto isLockRepeatNtPrefix = [](StringRef N) {
3524 return StringSwitch(N)
3525 .Cases({"lock", "rep", "repe", "repz", "repne", "repnz", "notrack"},
3526 true)
3528 };
3529
3530 bool CurlyAsEndOfStatement = false;
3531
3533 while (isLockRepeatNtPrefix(Name.lower())) {
3535 StringSwitch(Name)
3543
3544
3545
3547 break;
3548 }
3549
3551 Parser.Lex();
3552
3553
3554 while (Name.starts_with(";") || Name.starts_with("\n") ||
3555 Name.starts_with("#") || Name.starts_with("\t") ||
3556 Name.starts_with("/")) {
3557
3559 Parser.Lex();
3560 }
3561 }
3562
3563 if (Flags)
3564 PatchedName = Name;
3565
3566
3567 if (PatchedName == "data16" && is16BitMode()) {
3568 return Error(NameLoc, "redundant data16 prefix");
3569 }
3570 if (PatchedName == "data32") {
3571 if (is32BitMode())
3572 return Error(NameLoc, "redundant data32 prefix");
3573 if (is64BitMode())
3574 return Error(NameLoc, "'data32' is not supported in 64-bit mode");
3575
3576 PatchedName = "data16";
3577
3580 getLexer().Lex();
3581
3582
3583 if (Next == "callw")
3584 Next = "calll";
3585 if (Next == "ljmpw")
3586 Next = "ljmpl";
3587
3589 PatchedName = Name;
3590 ForcedDataPrefix = X86::Is32Bit;
3591 IsPrefix = false;
3592 }
3593 }
3594
3596
3597
3598 if (ComparisonPredicate != ~0U && !isParsingIntelSyntax()) {
3602 }
3603
3604
3605 if ((Name.starts_with("ccmp") || Name.starts_with("ctest")) &&
3606 parseCFlagsOp(Operands))
3607 return true;
3608
3609
3610
3611
3612
3614
3617
3618
3619 while (true) {
3620 if (parseOperand(Operands, Name))
3621 return true;
3622 if (HandleAVX512Operand(Operands))
3623 return true;
3624
3625
3627 Parser.Lex();
3628 else
3629 break;
3630 }
3631
3632
3633
3634 CurlyAsEndOfStatement =
3635 isParsingIntelSyntax() && isParsingMSInlineAsm() &&
3638 return TokError("unexpected token in argument list");
3639 }
3640
3641
3642 if (ComparisonPredicate != ~0U && isParsingIntelSyntax()) {
3646 }
3647
3648
3651 Parser.Lex();
3652 else if (CurlyAsEndOfStatement)
3653
3655 getLexer().getTok().getLoc(), 0);
3656
3657
3658
3659
3660 bool IsFp =
3661 Name == "fsub" || Name == "fdiv" || Name == "fsubr" || Name == "fdivr";
3662 if (IsFp && Operands.size() == 1) {
3663 const char *Repl = StringSwitch<const char *>(Name)
3664 .Case("fsub", "fsubp")
3665 .Case("fdiv", "fdivp")
3666 .Case("fsubr", "fsubrp")
3667 .Case("fdivr", "fdivrp");
3668 static_cast<X86Operand &>(*Operands[0]).setTokenValue(Repl);
3669 }
3670
3671 if ((Name == "mov" || Name == "movw" || Name == "movl") &&
3672 (Operands.size() == 3)) {
3673 X86Operand &Op1 = (X86Operand &)*Operands[1];
3674 X86Operand &Op2 = (X86Operand &)*Operands[2];
3676
3677
3679 X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(
3681 (X86MCRegisterClasses[X86::GR16RegClassID].contains(Op1.getReg()) ||
3682 X86MCRegisterClasses[X86::GR32RegClassID].contains(Op1.getReg()))) {
3683
3684 if (Name != "mov" && Name[3] == (is16BitMode() ? 'l' : 'w')) {
3685 Name = is16BitMode() ? "movw" : "movl";
3687 }
3688
3689 MCRegister Reg =
3692 }
3693 }
3694
3695
3696
3697
3698 if ((Name == "outb" || Name == "outsb" || Name == "outw" || Name == "outsw" ||
3699 Name == "outl" || Name == "outsl" || Name == "out" || Name == "outs") &&
3700 Operands.size() == 3) {
3701 X86Operand &Op = (X86Operand &)*Operands.back();
3702 if (Op.isDXReg())
3704 Op.getEndLoc());
3705 }
3706
3707 if ((Name == "inb" || Name == "insb" || Name == "inw" || Name == "insw" ||
3708 Name == "inl" || Name == "insl" || Name == "in" || Name == "ins") &&
3709 Operands.size() == 3) {
3710 X86Operand &Op = (X86Operand &)*Operands[1];
3711 if (Op.isDXReg())
3713 Op.getEndLoc());
3714 }
3715
3717 bool HadVerifyError = false;
3718
3719
3720 if (Name.starts_with("ins") &&
3721 (Operands.size() == 1 || Operands.size() == 3) &&
3722 (Name == "insb" || Name == "insw" || Name == "insl" || Name == "insd" ||
3723 Name == "ins")) {
3724
3725 AddDefaultSrcDestOperands(TmpOperands,
3727 DefaultMemDIOperand(NameLoc));
3728 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3729 }
3730
3731
3732 if (Name.starts_with("outs") &&
3733 (Operands.size() == 1 || Operands.size() == 3) &&
3734 (Name == "outsb" || Name == "outsw" || Name == "outsl" ||
3735 Name == "outsd" || Name == "outs")) {
3736 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3738 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3739 }
3740
3741
3742
3743
3744 if (Name.starts_with("lods") &&
3745 (Operands.size() == 1 || Operands.size() == 2) &&
3746 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
3747 Name == "lodsl" || Name == "lodsd" || Name == "lodsq")) {
3748 TmpOperands.push_back(DefaultMemSIOperand(NameLoc));
3749 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3750 }
3751
3752
3753
3754
3755 if (Name.starts_with("stos") &&
3756 (Operands.size() == 1 || Operands.size() == 2) &&
3757 (Name == "stos" || Name == "stosb" || Name == "stosw" ||
3758 Name == "stosl" || Name == "stosd" || Name == "stosq")) {
3759 TmpOperands.push_back(DefaultMemDIOperand(NameLoc));
3760 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3761 }
3762
3763
3764
3765
3766 if (Name.starts_with("scas") &&
3767 (Operands.size() == 1 || Operands.size() == 2) &&
3768 (Name == "scas" || Name == "scasb" || Name == "scasw" ||
3769 Name == "scasl" || Name == "scasd" || Name == "scasq")) {
3770 TmpOperands.push_back(DefaultMemDIOperand(NameLoc));
3771 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3772 }
3773
3774
3775 if (Name.starts_with("cmps") &&
3776 (Operands.size() == 1 || Operands.size() == 3) &&
3777 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
3778 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
3779 AddDefaultSrcDestOperands(TmpOperands, DefaultMemDIOperand(NameLoc),
3780 DefaultMemSIOperand(NameLoc));
3781 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3782 }
3783
3784
3785 if (((Name.starts_with("movs") &&
3786 (Name == "movs" || Name == "movsb" || Name == "movsw" ||
3787 Name == "movsl" || Name == "movsd" || Name == "movsq")) ||
3788 (Name.starts_with("smov") &&
3789 (Name == "smov" || Name == "smovb" || Name == "smovw" ||
3790 Name == "smovl" || Name == "smovd" || Name == "smovq"))) &&
3791 (Operands.size() == 1 || Operands.size() == 3)) {
3792 if (Name == "movsd" && Operands.size() == 1 && !isParsingIntelSyntax())
3794 AddDefaultSrcDestOperands(TmpOperands, DefaultMemSIOperand(NameLoc),
3795 DefaultMemDIOperand(NameLoc));
3796 HadVerifyError = VerifyAndAdjustOperands(Operands, TmpOperands);
3797 }
3798
3799
3800 if (HadVerifyError) {
3801 return HadVerifyError;
3802 }
3803
3804
3805 if ((Name == "xlat" || Name == "xlatb") && Operands.size() == 2) {
3806 X86Operand &Op1 = static_cast<X86Operand &>(*Operands[1]);
3808 Warning(Op1.getStartLoc(), "memory operand is only for determining the "
3809 "size, (R|E)BX will be used for the location");
3811 static_cast<X86Operand &>(*Operands[0]).setTokenValue("xlatb");
3812 }
3813 }
3814
3815 if (Flags)
3817 return false;
3818}
3819
3822 unsigned Opcode = Inst.getOpcode();
3824 if (I == Table.end() || I->OldOpc != Opcode)
3825 return false;
3826
3828
3829
3830 if (X86::isBLENDVPD(Opcode) || X86::isBLENDVPS(Opcode) ||
3831 X86::isPBLENDVB(Opcode))
3833
3834 return true;
3835}
3836
3837bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
3839 return true;
3840
3841 if (ForcedOpcodePrefix != OpcodePrefix_VEX3 &&
3843 return true;
3844
3846 return true;
3847
3848 auto replaceWithCCMPCTEST = [&](unsigned Opcode) -> bool {
3849 if (ForcedOpcodePrefix == OpcodePrefix_EVEX) {
3854 return true;
3855 }
3856 return false;
3857 };
3858
3860 default: return false;
3861 case X86::JMP_1:
3862
3863
3864
3865 if (ForcedDispEncoding == DispEncoding_Disp32) {
3866 Inst.setOpcode(is16BitMode() ? X86::JMP_2 : X86::JMP_4);
3867 return true;
3868 }
3869
3870 return false;
3871 case X86::JCC_1:
3872
3873
3874
3875 if (ForcedDispEncoding == DispEncoding_Disp32) {
3876 Inst.setOpcode(is16BitMode() ? X86::JCC_2 : X86::JCC_4);
3877 return true;
3878 }
3879
3880 return false;
3881 case X86::INT: {
3882
3883
3885 return false;
3888 return true;
3889 }
3890
3891
3892#define FROM_TO(FROM, TO) \
3893 case X86::FROM: \
3894 return replaceWithCCMPCTEST(X86::TO);
3895 FROM_TO(CMP64rr, CCMP64rr)
3896 FROM_TO(CMP64mi32, CCMP64mi32)
3897 FROM_TO(CMP64mi8, CCMP64mi8)
3898 FROM_TO(CMP64mr, CCMP64mr)
3899 FROM_TO(CMP64ri32, CCMP64ri32)
3900 FROM_TO(CMP64ri8, CCMP64ri8)
3901 FROM_TO(CMP64rm, CCMP64rm)
3902
3903 FROM_TO(CMP32rr, CCMP32rr)
3904 FROM_TO(CMP32mi, CCMP32mi)
3905 FROM_TO(CMP32mi8, CCMP32mi8)
3906 FROM_TO(CMP32mr, CCMP32mr)
3907 FROM_TO(CMP32ri, CCMP32ri)
3908 FROM_TO(CMP32ri8, CCMP32ri8)
3909 FROM_TO(CMP32rm, CCMP32rm)
3910
3911 FROM_TO(CMP16rr, CCMP16rr)
3912 FROM_TO(CMP16mi, CCMP16mi)
3913 FROM_TO(CMP16mi8, CCMP16mi8)
3914 FROM_TO(CMP16mr, CCMP16mr)
3915 FROM_TO(CMP16ri, CCMP16ri)
3916 FROM_TO(CMP16ri8, CCMP16ri8)
3917 FROM_TO(CMP16rm, CCMP16rm)
3918
3919 FROM_TO(CMP8rr, CCMP8rr)
3920 FROM_TO(CMP8mi, CCMP8mi)
3921 FROM_TO(CMP8mr, CCMP8mr)
3922 FROM_TO(CMP8ri, CCMP8ri)
3923 FROM_TO(CMP8rm, CCMP8rm)
3924
3925 FROM_TO(TEST64rr, CTEST64rr)
3926 FROM_TO(TEST64mi32, CTEST64mi32)
3927 FROM_TO(TEST64mr, CTEST64mr)
3928 FROM_TO(TEST64ri32, CTEST64ri32)
3929
3930 FROM_TO(TEST32rr, CTEST32rr)
3931 FROM_TO(TEST32mi, CTEST32mi)
3932 FROM_TO(TEST32mr, CTEST32mr)
3933 FROM_TO(TEST32ri, CTEST32ri)
3934
3935 FROM_TO(TEST16rr, CTEST16rr)
3936 FROM_TO(TEST16mi, CTEST16mi)
3937 FROM_TO(TEST16mr, CTEST16mr)
3938 FROM_TO(TEST16ri, CTEST16ri)
3939
3940 FROM_TO(TEST8rr, CTEST8rr)
3941 FROM_TO(TEST8mi, CTEST8mi)
3942 FROM_TO(TEST8mr, CTEST8mr)
3943 FROM_TO(TEST8ri, CTEST8ri)
3944#undef FROM_TO
3945 }
3946}
3947
3948bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
3949 using namespace X86;
3950 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
3951 unsigned Opcode = Inst.getOpcode();
3952 uint64_t TSFlags = MII.get(Opcode).TSFlags;
3953 if (isVFCMADDCPH(Opcode) || isVFCMADDCSH(Opcode) || isVFMADDCPH(Opcode) ||
3954 isVFMADDCSH(Opcode)) {
3956 for (unsigned i = 2; i < Inst.getNumOperands(); i++)
3958 return Warning(Ops[0]->getStartLoc(), "Destination register should be "
3959 "distinct from source registers");
3960 } else if (isVFCMULCPH(Opcode) || isVFCMULCSH(Opcode) || isVFMULCPH(Opcode) ||
3961 isVFMULCSH(Opcode)) {
3963
3964
3965
3966
3967
3968 for (unsigned i = ((TSFlags & X86II::EVEX_K) ? 2 : 1);
3971 return Warning(Ops[0]->getStartLoc(), "Destination register should be "
3972 "distinct from source registers");
3973 } else if (isV4FMADDPS(Opcode) || isV4FMADDSS(Opcode) ||
3974 isV4FNMADDPS(Opcode) || isV4FNMADDSS(Opcode) ||
3975 isVP4DPWSSDS(Opcode) || isVP4DPWSSD(Opcode)) {
3976 MCRegister Src2 =
3979 unsigned Src2Enc = MRI->getEncodingValue(Src2);
3980 if (Src2Enc % 4 != 0) {
3982 unsigned GroupStart = (Src2Enc / 4) * 4;
3983 unsigned GroupEnd = GroupStart + 3;
3984 return Warning(Ops[0]->getStartLoc(),
3985 "source register '" + RegName + "' implicitly denotes '" +
3986 RegName.take_front(3) + Twine(GroupStart) + "' to '" +
3987 RegName.take_front(3) + Twine(GroupEnd) +
3988 "' source group");
3989 }
3990 } else if (isVGATHERDPD(Opcode) || isVGATHERDPS(Opcode) ||
3991 isVGATHERQPD(Opcode) || isVGATHERQPS(Opcode) ||
3992 isVPGATHERDD(Opcode) || isVPGATHERDQ(Opcode) ||
3993 isVPGATHERQD(Opcode) || isVPGATHERQQ(Opcode)) {
3995 if (HasEVEX) {
3997 unsigned Index = MRI->getEncodingValue(
3999 if (Dest == Index)
4000 return Warning(Ops[0]->getStartLoc(), "index and destination registers "
4001 "should be distinct");
4002 } else {
4005 unsigned Index = MRI->getEncodingValue(
4007 if (Dest == Mask || Dest == Index || Mask == Index)
4008 return Warning(Ops[0]->getStartLoc(), "mask, index, and destination "
4009 "registers should be distinct");
4010 }
4011 } else if (isTCMMIMFP16PS(Opcode) || isTCMMRLFP16PS(Opcode) ||
4012 isTDPBF16PS(Opcode) || isTDPFP16PS(Opcode) || isTDPBSSD(Opcode) ||
4013 isTDPBSUD(Opcode) || isTDPBUSD(Opcode) || isTDPBUUD(Opcode)) {
4017 if (SrcDest == Src1 || SrcDest == Src2 || Src1 == Src2)
4018 return Error(Ops[0]->getStartLoc(), "all tmm registers must be distinct");
4019 }
4020
4021
4022
4023
4024
4025
4026
4029 MCRegister HReg;
4032 for (unsigned i = 0; i != NumOps; ++i) {
4033 const MCOperand &MO = Inst.getOperand(i);
4034 if (!MO.isReg())
4035 continue;
4037 if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH)
4038 HReg = Reg;
4041 UsesRex = true;
4042 }
4043
4044 if (HReg &&
4045 (Enc == X86II::EVEX || ForcedOpcodePrefix == OpcodePrefix_REX2 ||
4046 ForcedOpcodePrefix == OpcodePrefix_REX || UsesRex)) {
4048 return Error(Ops[0]->getStartLoc(),
4049 "can't encode '" + RegName.str() +
4050 "' in an instruction requiring EVEX/REX2/REX prefix");
4051 }
4052 }
4053
4054 if ((Opcode == X86::PREFETCHIT0 || Opcode == X86::PREFETCHIT1)) {
4056 if (!MO.isReg() || MO.getReg() != X86::RIP)
4058 Ops[0]->getStartLoc(),
4059 Twine((Inst.getOpcode() == X86::PREFETCHIT0 ? "'prefetchit0'"
4060 : "'prefetchit1'")) +
4061 " only supports RIP-relative address");
4062 }
4063 return false;
4064}
4065
4066void X86AsmParser::emitWarningForSpecialLVIInstruction(SMLoc Loc) {
4067 Warning(Loc, "Instruction may be vulnerable to LVI and "
4068 "requires manual mitigation");
4069 Note(SMLoc(), "See https://software.intel.com/"
4070 "security-software-guidance/insights/"
4071 "deep-dive-load-value-injection#specialinstructions"
4072 " for more information");
4073}
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084void X86AsmParser::applyLVICFIMitigation(MCInst &Inst, MCStreamer &Out) {
4085
4086
4087
4089 case X86::RET16:
4090 case X86::RET32:
4091 case X86::RET64:
4092 case X86::RETI16:
4093 case X86::RETI32:
4094 case X86::RETI64: {
4095 MCInst ShlInst, FenceInst;
4096 bool Parse32 = is32BitMode() || Code16GCC;
4097 MCRegister Basereg =
4098 is64BitMode() ? X86::RSP : (Parse32 ? X86::ESP : X86::SP);
4101 Basereg, 0,
4102 1, SMLoc{}, SMLoc{}, 0);
4103 ShlInst.setOpcode(X86::SHL64mi);
4104 ShlMemOp->addMemOperands(ShlInst, 5);
4106 FenceInst.setOpcode(X86::LFENCE);
4109 return;
4110 }
4111 case X86::JMP16m:
4112 case X86::JMP32m:
4113 case X86::JMP64m:
4114 case X86::CALL16m:
4115 case X86::CALL32m:
4116 case X86::CALL64m:
4117 emitWarningForSpecialLVIInstruction(Inst.getLoc());
4118 return;
4119 }
4120}
4121
4122
4123
4124
4125
4126
4127
4128
4129void X86AsmParser::applyLVILoadHardeningMitigation(MCInst &Inst,
4130 MCStreamer &Out) {
4134
4135
4136
4137 switch (Opcode) {
4138 case X86::CMPSB:
4139 case X86::CMPSW:
4140 case X86::CMPSL:
4141 case X86::CMPSQ:
4142 case X86::SCASB:
4143 case X86::SCASW:
4144 case X86::SCASL:
4145 case X86::SCASQ:
4146 emitWarningForSpecialLVIInstruction(Inst.getLoc());
4147 return;
4148 }
4149 } else if (Opcode == X86::REP_PREFIX || Opcode == X86::REPNE_PREFIX) {
4150
4151
4152 emitWarningForSpecialLVIInstruction(Inst.getLoc());
4153 return;
4154 }
4155
4156 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
4157
4158
4159
4161 return;
4162
4163
4165 MCInst FenceInst;
4166 FenceInst.setOpcode(X86::LFENCE);
4168 }
4169}
4170
4171void X86AsmParser::emitInstruction(MCInst &Inst, OperandVector &Operands,
4172 MCStreamer &Out) {
4174 getSTI().hasFeature(X86::FeatureLVIControlFlowIntegrity))
4175 applyLVICFIMitigation(Inst, Out);
4176
4178
4180 getSTI().hasFeature(X86::FeatureLVILoadHardening))
4181 applyLVILoadHardeningMitigation(Inst, Out);
4182}
4183
4185 unsigned Result = 0;
4187 if (Prefix.isPrefix()) {
4188 Result = Prefix.getPrefix();
4190 }
4191 return Result;
4192}
4193
4194bool X86AsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
4196 MCStreamer &Out, uint64_t &ErrorInfo,
4197 bool MatchingInlineAsm) {
4198 assert(!Operands.empty() && "Unexpect empty operand list!");
4199 assert((*Operands[0]).isToken() && "Leading operand should always be a mnemonic!");
4200
4201
4202 MatchFPUWaitAlias(IDLoc, static_cast<X86Operand &>(*Operands[0]), Operands,
4203 Out, MatchingInlineAsm);
4204 unsigned Prefixes = getPrefixes(Operands);
4205
4206 MCInst Inst;
4207
4208
4209
4210 if (ForcedOpcodePrefix == OpcodePrefix_REX)
4212 else if (ForcedOpcodePrefix == OpcodePrefix_REX2)
4214 else if (ForcedOpcodePrefix == OpcodePrefix_VEX)
4216 else if (ForcedOpcodePrefix == OpcodePrefix_VEX2)
4218 else if (ForcedOpcodePrefix == OpcodePrefix_VEX3)
4220 else if (ForcedOpcodePrefix == OpcodePrefix_EVEX)
4222
4223
4224 if (ForcedDispEncoding == DispEncoding_Disp8)
4226 else if (ForcedDispEncoding == DispEncoding_Disp32)
4228
4229 if (Prefixes)
4231
4232 return isParsingIntelSyntax()
4233 ? matchAndEmitIntelInstruction(IDLoc, Opcode, Inst, Operands, Out,
4234 ErrorInfo, MatchingInlineAsm)
4235 : matchAndEmitATTInstruction(IDLoc, Opcode, Inst, Operands, Out,
4236 ErrorInfo, MatchingInlineAsm);
4237}
4238
4239void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
4241 bool MatchingInlineAsm) {
4242
4243
4244
4245 const char *Repl = StringSwitch<const char *>(Op.getToken())
4246 .Case("finit", "fninit")
4247 .Case("fsave", "fnsave")
4248 .Case("fstcw", "fnstcw")
4249 .Case("fstcww", "fnstcw")
4250 .Case("fstenv", "fnstenv")
4251 .Case("fstsw", "fnstsw")
4252 .Case("fstsww", "fnstsw")
4253 .Case("fclex", "fnclex")
4254 .Default(nullptr);
4255 if (Repl) {
4256 MCInst Inst;
4259 if (!MatchingInlineAsm)
4262 }
4263}
4264
4265bool X86AsmParser::ErrorMissingFeature(SMLoc IDLoc,
4266 const FeatureBitset &MissingFeatures,
4267 bool MatchingInlineAsm) {
4268 assert(MissingFeatures.any() && "Unknown missing feature!");
4269 SmallString<126> Msg;
4270 raw_svector_ostream OS(Msg);
4271 OS << "instruction requires:";
4272 for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {
4273 if (MissingFeatures[i])
4275 }
4276 return Error(IDLoc, OS.str(), SMRange(), MatchingInlineAsm);
4277}
4278
4279unsigned X86AsmParser::checkTargetMatchPredicate(MCInst &Inst) {
4281 const MCInstrDesc &MCID = MII.get(Opc);
4282 uint64_t TSFlags = MCID.TSFlags;
4283
4285 return Match_Unsupported;
4286 if (ForcedNoFlag == !(TSFlags & X86II::EVEX_NF) && !X86::isCFCMOVCC(Opc))
4287 return Match_Unsupported;
4288
4289 switch (ForcedOpcodePrefix) {
4290 case OpcodePrefix_Default:
4291 break;
4292 case OpcodePrefix_REX:
4293 case OpcodePrefix_REX2:
4295 return Match_Unsupported;
4296 break;
4297 case OpcodePrefix_VEX:
4298 case OpcodePrefix_VEX2:
4299 case OpcodePrefix_VEX3:
4301 return Match_Unsupported;
4302 break;
4303 case OpcodePrefix_EVEX:
4305 !X86::isCMP(Opc) && !X86::isTEST(Opc))
4306 return Match_Unsupported;
4308 return Match_Unsupported;
4309 break;
4310 }
4311
4313 (ForcedOpcodePrefix != OpcodePrefix_VEX &&
4314 ForcedOpcodePrefix != OpcodePrefix_VEX2 &&
4315 ForcedOpcodePrefix != OpcodePrefix_VEX3))
4316 return Match_Unsupported;
4317
4318 return Match_Success;
4319}
4320
4321bool X86AsmParser::matchAndEmitATTInstruction(
4322 SMLoc IDLoc, unsigned &Opcode, MCInst &Inst, OperandVector &Operands,
4323 MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm) {
4324 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
4325 SMRange EmptyRange;
4326
4327
4328 if (ForcedDataPrefix == X86::Is32Bit)
4329 SwitchMode(X86::Is32Bit);
4330
4331 FeatureBitset MissingFeatures;
4332 unsigned OriginalError = MatchInstruction(Operands, Inst, ErrorInfo,
4333 MissingFeatures, MatchingInlineAsm,
4334 isParsingIntelSyntax());
4335 if (ForcedDataPrefix == X86::Is32Bit) {
4336 SwitchMode(X86::Is16Bit);
4337 ForcedDataPrefix = 0;
4338 }
4339 switch (OriginalError) {
4341 case Match_Success:
4342 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4343 return true;
4344
4345
4346
4347 if (!MatchingInlineAsm)
4348 while (processInstruction(Inst, Operands))
4349 ;
4350
4352 if (!MatchingInlineAsm)
4355 return false;
4356 case Match_InvalidImmUnsignedi4: {
4357 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4358 if (ErrorLoc == SMLoc())
4359 ErrorLoc = IDLoc;
4360 return Error(ErrorLoc, "immediate must be an integer in range [0, 15]",
4361 EmptyRange, MatchingInlineAsm);
4362 }
4363 case Match_MissingFeature:
4364 return ErrorMissingFeature(IDLoc, MissingFeatures, MatchingInlineAsm);
4365 case Match_InvalidOperand:
4366 case Match_MnemonicFail:
4367 case Match_Unsupported:
4368 break;
4369 }
4370 if (Op.getToken().empty()) {
4371 Error(IDLoc, "instruction must have size higher than 0", EmptyRange,
4372 MatchingInlineAsm);
4373 return true;
4374 }
4375
4376
4377
4378
4379
4380
4381
4382 StringRef Base = Op.getToken();
4383 SmallString<16> Tmp;
4384 Tmp += Base;
4385 Tmp += ' ';
4386 Op.setTokenValue(Tmp);
4387
4388
4389
4390
4391
4392
4393
4394 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
4395
4396 const char *MemSize = Base[0] != 'f' ? "\x08\x10\x20\x40" : "\x20\x40\x50\0";
4397
4398
4399 uint64_t ErrorInfoIgnore;
4400 FeatureBitset ErrorInfoMissingFeatures;
4401 unsigned Match[4];
4402
4403
4404
4405
4406
4407
4408 bool HasVectorReg = false;
4409 X86Operand *MemOp = nullptr;
4410 for (const auto &Op : Operands) {
4411 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
4413 HasVectorReg = true;
4414 else if (X86Op->isMem()) {
4415 MemOp = X86Op;
4416 assert(MemOp->Mem.Size == 0 && "Memory size always 0 under ATT syntax");
4417
4418
4419 break;
4420 }
4421 }
4422
4423 for (unsigned I = 0, E = std::size(Match); I != E; ++I) {
4424 Tmp.back() = Suffixes[I];
4425 if (MemOp && HasVectorReg)
4426 MemOp->Mem.Size = MemSize[I];
4427 Match[I] = Match_MnemonicFail;
4428 if (MemOp || !HasVectorReg) {
4429 Match[I] =
4430 MatchInstruction(Operands, Inst, ErrorInfoIgnore, MissingFeatures,
4431 MatchingInlineAsm, isParsingIntelSyntax());
4432
4433 if (Match[I] == Match_MissingFeature)
4434 ErrorInfoMissingFeatures = MissingFeatures;
4435 }
4436 }
4437
4438
4440
4441
4442
4443
4444 unsigned NumSuccessfulMatches = llvm::count(Match, Match_Success);
4445 if (NumSuccessfulMatches == 1) {
4446 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4447 return true;
4448
4449
4450
4451 if (!MatchingInlineAsm)
4452 while (processInstruction(Inst, Operands))
4453 ;
4454
4456 if (!MatchingInlineAsm)
4459 return false;
4460 }
4461
4462
4463
4464
4465
4466 if (NumSuccessfulMatches > 1) {
4467 char MatchChars[4];
4468 unsigned NumMatches = 0;
4469 for (unsigned I = 0, E = std::size(Match); I != E; ++I)
4470 if (Match[I] == Match_Success)
4471 MatchChars[NumMatches++] = Suffixes[I];
4472
4473 SmallString<126> Msg;
4474 raw_svector_ostream OS(Msg);
4475 OS << "ambiguous instructions require an explicit suffix (could be ";
4476 for (unsigned i = 0; i != NumMatches; ++i) {
4477 if (i != 0)
4478 OS << ", ";
4479 if (i + 1 == NumMatches)
4480 OS << "or ";
4481 OS << "'" << Base << MatchChars[i] << "'";
4482 }
4483 OS << ")";
4484 Error(IDLoc, OS.str(), EmptyRange, MatchingInlineAsm);
4485 return true;
4486 }
4487
4488
4489
4490
4491
4492 if (llvm::count(Match, Match_MnemonicFail) == 4) {
4493 if (OriginalError == Match_MnemonicFail)
4494 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
4495 Op.getLocRange(), MatchingInlineAsm);
4496
4497 if (OriginalError == Match_Unsupported)
4498 return Error(IDLoc, "unsupported instruction", EmptyRange,
4499 MatchingInlineAsm);
4500
4501 assert(OriginalError == Match_InvalidOperand && "Unexpected error");
4502
4503 if (ErrorInfo != ~0ULL) {
4504 if (ErrorInfo >= Operands.size())
4505 return Error(IDLoc, "too few operands for instruction", EmptyRange,
4506 MatchingInlineAsm);
4507
4508 X86Operand &Operand = (X86Operand &)*Operands[ErrorInfo];
4510 SMRange OperandRange = Operand.getLocRange();
4511 return Error(Operand.getStartLoc(), "invalid operand for instruction",
4512 OperandRange, MatchingInlineAsm);
4513 }
4514 }
4515
4516 return Error(IDLoc, "invalid operand for instruction", EmptyRange,
4517 MatchingInlineAsm);
4518 }
4519
4520
4521 if (llvm::count(Match, Match_Unsupported) == 1) {
4522 return Error(IDLoc, "unsupported instruction", EmptyRange,
4523 MatchingInlineAsm);
4524 }
4525
4526
4527
4528 if (llvm::count(Match, Match_MissingFeature) == 1) {
4529 ErrorInfo = Match_MissingFeature;
4530 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4531 MatchingInlineAsm);
4532 }
4533
4534
4535
4536 if (llvm::count(Match, Match_InvalidOperand) == 1) {
4537 return Error(IDLoc, "invalid operand for instruction", EmptyRange,
4538 MatchingInlineAsm);
4539 }
4540
4541
4542 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
4543 EmptyRange, MatchingInlineAsm);
4544 return true;
4545}
4546
4547bool X86AsmParser::matchAndEmitIntelInstruction(
4548 SMLoc IDLoc, unsigned &Opcode, MCInst &Inst, OperandVector &Operands,
4549 MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm) {
4550 X86Operand &Op = static_cast<X86Operand &>(*Operands[0]);
4551 SMRange EmptyRange;
4552
4553 X86Operand *UnsizedMemOp = nullptr;
4554 for (const auto &Op : Operands) {
4555 X86Operand *X86Op = static_cast<X86Operand *>(Op.get());
4557 UnsizedMemOp = X86Op;
4558
4559
4560 break;
4561 }
4562 }
4563
4564
4565
4566 StringRef Mnemonic = (static_cast<X86Operand &>(*Operands[0])).getToken();
4567 if (UnsizedMemOp) {
4568 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push", "pop"};
4569 for (const char *Instr : PtrSizedInstrs) {
4570 if (Mnemonic == Instr) {
4571 UnsizedMemOp->Mem.Size = getPointerWidth();
4572 break;
4573 }
4574 }
4575 }
4576
4577 SmallVector<unsigned, 8> Match;
4578 FeatureBitset ErrorInfoMissingFeatures;
4579 FeatureBitset MissingFeatures;
4580 StringRef Base = (static_cast<X86Operand &>(*Operands[0])).getToken();
4581
4582
4583
4584 if (Mnemonic == "push" && Operands.size() == 2) {
4585 auto *X86Op = static_cast<X86Operand *>(Operands[1].get());
4586 if (X86Op->isImm()) {
4587
4589 unsigned Size = getPointerWidth();
4590 if (CE &&
4592 SmallString<16> Tmp;
4593 Tmp += Base;
4594 Tmp += (is64BitMode())
4595 ? "q"
4596 : (is32BitMode()) ? "l" : (is16BitMode()) ? "w" : " ";
4597 Op.setTokenValue(Tmp);
4598
4599 Match.push_back(MatchInstruction(Operands, Inst, ErrorInfo,
4600 MissingFeatures, MatchingInlineAsm,
4601 false ));
4603 }
4604 }
4605 }
4606
4607
4608
4609
4610 if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) {
4611 static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512};
4612 for (unsigned Size : MopSizes) {
4614 uint64_t ErrorInfoIgnore;
4615 unsigned LastOpcode = Inst.getOpcode();
4616 unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
4617 MissingFeatures, MatchingInlineAsm,
4618 isParsingIntelSyntax());
4619 if (Match.empty() || LastOpcode != Inst.getOpcode())
4621
4622
4623 if (Match.back() == Match_MissingFeature)
4624 ErrorInfoMissingFeatures = MissingFeatures;
4625 }
4626
4627
4628 UnsizedMemOp->Mem.Size = 0;
4629 }
4630
4631
4632
4633
4634 if (Match.empty()) {
4635 Match.push_back(MatchInstruction(
4636 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4637 isParsingIntelSyntax()));
4638
4639 if (Match.back() == Match_MissingFeature)
4640 ErrorInfoMissingFeatures = MissingFeatures;
4641 }
4642
4643
4644 if (UnsizedMemOp)
4645 UnsizedMemOp->Mem.Size = 0;
4646
4647
4648 if (Match.back() == Match_MnemonicFail) {
4649 return Error(IDLoc, "invalid instruction mnemonic '" + Mnemonic + "'",
4650 Op.getLocRange(), MatchingInlineAsm);
4651 }
4652
4653 unsigned NumSuccessfulMatches = llvm::count(Match, Match_Success);
4654
4655
4656
4657 if (UnsizedMemOp && NumSuccessfulMatches > 1 &&
4660 unsigned M = MatchInstruction(
4661 Operands, Inst, ErrorInfo, MissingFeatures, MatchingInlineAsm,
4662 isParsingIntelSyntax());
4663 if (M == Match_Success)
4664 NumSuccessfulMatches = 1;
4665
4666
4667
4671 }
4672
4673
4674
4675
4676 if (NumSuccessfulMatches == 1) {
4677 if (!MatchingInlineAsm && validateInstruction(Inst, Operands))
4678 return true;
4679
4680
4681
4682 if (!MatchingInlineAsm)
4683 while (processInstruction(Inst, Operands))
4684 ;
4686 if (!MatchingInlineAsm)
4689 return false;
4690 } else if (NumSuccessfulMatches > 1) {
4691 assert(UnsizedMemOp &&
4692 "multiple matches only possible with unsized memory operands");
4694 "ambiguous operand size for instruction '" + Mnemonic + "\'",
4696 }
4697
4698
4699 if (llvm::count(Match, Match_Unsupported) == 1) {
4700 return Error(IDLoc, "unsupported instruction", EmptyRange,
4701 MatchingInlineAsm);
4702 }
4703
4704
4705
4706 if (llvm::count(Match, Match_MissingFeature) == 1) {
4707 ErrorInfo = Match_MissingFeature;
4708 return ErrorMissingFeature(IDLoc, ErrorInfoMissingFeatures,
4709 MatchingInlineAsm);
4710 }
4711
4712
4713
4714 if (llvm::count(Match, Match_InvalidOperand) == 1) {
4715 return Error(IDLoc, "invalid operand for instruction", EmptyRange,
4716 MatchingInlineAsm);
4717 }
4718
4719 if (llvm::count(Match, Match_InvalidImmUnsignedi4) == 1) {
4720 SMLoc ErrorLoc = ((X86Operand &)*Operands[ErrorInfo]).getStartLoc();
4721 if (ErrorLoc == SMLoc())
4722 ErrorLoc = IDLoc;
4723 return Error(ErrorLoc, "immediate must be an integer in range [0, 15]",
4724 EmptyRange, MatchingInlineAsm);
4725 }
4726
4727
4728 return Error(IDLoc, "unknown instruction mnemonic", EmptyRange,
4729 MatchingInlineAsm);
4730}
4731
4732bool X86AsmParser::omitRegisterFromClobberLists(MCRegister Reg) {
4733 return X86MCRegisterClasses[X86::SEGMENT_REGRegClassID].contains(Reg);
4734}
4735
4736bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
4737 MCAsmParser &Parser = getParser();
4740 return parseDirectiveArch();
4742 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
4743 else if (IDVal.starts_with(".att_syntax")) {
4746 Parser.Lex();
4748 return Error(DirectiveID.getLoc(), "'.att_syntax noprefix' is not "
4749 "supported: registers must have a "
4750 "'%' prefix in .att_syntax");
4751 }
4752 getParser().setAssemblerDialect(0);
4753 return false;
4754 } else if (IDVal.starts_with(".intel_syntax")) {
4755 getParser().setAssemblerDialect(1);
4758 Parser.Lex();
4760 return Error(DirectiveID.getLoc(), "'.intel_syntax prefix' is not "
4761 "supported: registers must not have "
4762 "a '%' prefix in .intel_syntax");
4763 }
4764 return false;
4765 } else if (IDVal == ".nops")
4766 return parseDirectiveNops(DirectiveID.getLoc());
4767 else if (IDVal == ".even")
4768 return parseDirectiveEven(DirectiveID.getLoc());
4769 else if (IDVal == ".cv_fpo_proc")
4770 return parseDirectiveFPOProc(DirectiveID.getLoc());
4771 else if (IDVal == ".cv_fpo_setframe")
4772 return parseDirectiveFPOSetFrame(DirectiveID.getLoc());
4773 else if (IDVal == ".cv_fpo_pushreg")
4774 return parseDirectiveFPOPushReg(DirectiveID.getLoc());
4775 else if (IDVal == ".cv_fpo_stackalloc")
4776 return parseDirectiveFPOStackAlloc(DirectiveID.getLoc());
4777 else if (IDVal == ".cv_fpo_stackalign")
4778 return parseDirectiveFPOStackAlign(DirectiveID.getLoc());
4779 else if (IDVal == ".cv_fpo_endprologue")
4780 return parseDirectiveFPOEndPrologue(DirectiveID.getLoc());
4781 else if (IDVal == ".cv_fpo_endproc")
4782 return parseDirectiveFPOEndProc(DirectiveID.getLoc());
4783 else if (IDVal == ".seh_pushreg" ||
4785 return parseDirectiveSEHPushReg(DirectiveID.getLoc());
4786 else if (IDVal == ".seh_setframe" ||
4788 return parseDirectiveSEHSetFrame(DirectiveID.getLoc());
4789 else if (IDVal == ".seh_savereg" ||
4791 return parseDirectiveSEHSaveReg(DirectiveID.getLoc());
4792 else if (IDVal == ".seh_savexmm" ||
4794 return parseDirectiveSEHSaveXMM(DirectiveID.getLoc());
4795 else if (IDVal == ".seh_pushframe" ||
4797 return parseDirectiveSEHPushFrame(DirectiveID.getLoc());
4798
4799 return true;
4800}
4801
4802bool X86AsmParser::parseDirectiveArch() {
4803
4804 getParser().parseStringToEndOfStatement();
4805 return false;
4806}
4807
4808
4809
4810bool X86AsmParser::parseDirectiveNops(SMLoc L) {
4811 int64_t NumBytes = 0, Control = 0;
4812 SMLoc NumBytesLoc, ControlLoc;
4813 const MCSubtargetInfo& STI = getSTI();
4814 NumBytesLoc = getTok().getLoc();
4815 if (getParser().checkForValidSection() ||
4816 getParser().parseAbsoluteExpression(NumBytes))
4817 return true;
4818
4820 ControlLoc = getTok().getLoc();
4821 if (getParser().parseAbsoluteExpression(Control))
4822 return true;
4823 }
4824 if (getParser().parseEOL())
4825 return true;
4826
4827 if (NumBytes <= 0) {
4828 Error(NumBytesLoc, "'.nops' directive with non-positive size");
4829 return false;
4830 }
4831
4832 if (Control < 0) {
4833 Error(ControlLoc, "'.nops' directive with negative NOP size");
4834 return false;
4835 }
4836
4837
4838 getParser().getStreamer().emitNops(NumBytes, Control, L, STI);
4839
4840 return false;
4841}
4842
4843
4844
4845bool X86AsmParser::parseDirectiveEven(SMLoc L) {
4846 if (parseEOL())
4847 return false;
4848
4849 const MCSection *Section = getStreamer().getCurrentSectionOnly();
4850 if (!Section) {
4851 getStreamer().initSections(false, getSTI());
4852 Section = getStreamer().getCurrentSectionOnly();
4853 }
4854 if (getContext().getAsmInfo()->useCodeAlign(*Section))
4855 getStreamer().emitCodeAlignment(Align(2), &getSTI(), 0);
4856 else
4857 getStreamer().emitValueToAlignment(Align(2), 0, 1, 0);
4858 return false;
4859}
4860
4861
4862
4863bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
4864 MCAsmParser &Parser = getParser();
4865 Code16GCC = false;
4866 if (IDVal == ".code16") {
4867 Parser.Lex();
4868 if (!is16BitMode()) {
4869 SwitchMode(X86::Is16Bit);
4870 getTargetStreamer().emitCode16();
4871 }
4872 } else if (IDVal == ".code16gcc") {
4873
4874 Parser.Lex();
4875 Code16GCC = true;
4876 if (!is16BitMode()) {
4877 SwitchMode(X86::Is16Bit);
4878 getTargetStreamer().emitCode16();
4879 }
4880 } else if (IDVal == ".code32") {
4881 Parser.Lex();
4882 if (!is32BitMode()) {
4883 SwitchMode(X86::Is32Bit);
4884 getTargetStreamer().emitCode32();
4885 }
4886 } else if (IDVal == ".code64") {
4887 Parser.Lex();
4888 if (!is64BitMode()) {
4889 SwitchMode(X86::Is64Bit);
4890 getTargetStreamer().emitCode64();
4891 }
4892 } else {
4893 Error(L, "unknown directive " + IDVal);
4894 return false;
4895 }
4896
4897 return false;
4898}
4899
4900
4901bool X86AsmParser::parseDirectiveFPOProc(SMLoc L) {
4902 MCAsmParser &Parser = getParser();
4903 StringRef ProcName;
4904 int64_t ParamsSize;
4906 return Parser.TokError("expected symbol name");
4907 if (Parser.parseIntToken(ParamsSize, "expected parameter byte count"))
4908 return true;
4909 if ((32, ParamsSize))
4910 return Parser.TokError("parameters size out of range");
4911 if (parseEOL())
4912 return true;
4914 return getTargetStreamer().emitFPOProc(ProcSym, ParamsSize, L);
4915}
4916
4917
4918bool X86AsmParser::parseDirectiveFPOSetFrame(SMLoc L) {
4919 MCRegister Reg;
4920 SMLoc DummyLoc;
4921 if (parseRegister(Reg, DummyLoc, DummyLoc) || parseEOL())
4922 return true;
4923 return getTargetStreamer().emitFPOSetFrame(Reg, L);
4924}
4925
4926
4927bool X86AsmParser::parseDirectiveFPOPushReg(SMLoc L) {
4928 MCRegister Reg;
4929 SMLoc DummyLoc;
4930 if (parseRegister(Reg, DummyLoc, DummyLoc) || parseEOL())
4931 return true;
4932 return getTargetStreamer().emitFPOPushReg(Reg, L);
4933}
4934
4935
4936bool X86AsmParser::parseDirectiveFPOStackAlloc(SMLoc L) {
4937 MCAsmParser &Parser = getParser();
4940 return true;
4941 return getTargetStreamer().emitFPOStackAlloc(Offset, L);
4942}
4943
4944
4945bool X86AsmParser::parseDirectiveFPOStackAlign(SMLoc L) {
4946 MCAsmParser &Parser = getParser();
4949 return true;
4950 return getTargetStreamer().emitFPOStackAlign(Offset, L);
4951}
4952
4953
4954bool X86AsmParser::parseDirectiveFPOEndPrologue(SMLoc L) {
4955 MCAsmParser &Parser = getParser();
4957 return true;
4958 return getTargetStreamer().emitFPOEndPrologue(L);
4959}
4960
4961
4962bool X86AsmParser::parseDirectiveFPOEndProc(SMLoc L) {
4963 MCAsmParser &Parser = getParser();
4965 return true;
4966 return getTargetStreamer().emitFPOEndProc(L);
4967}
4968
4969bool X86AsmParser::parseSEHRegisterNumber(unsigned RegClassID,
4970 MCRegister &RegNo) {
4971 SMLoc startLoc = getLexer().getLoc();
4972 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
4973
4974
4976 SMLoc endLoc;
4977 if (parseRegister(RegNo, startLoc, endLoc))
4978 return true;
4979
4980 if (!X86MCRegisterClasses[RegClassID].contains(RegNo)) {
4981 return Error(startLoc,
4982 "register is not supported for use with this directive");
4983 }
4984 } else {
4985
4986
4987 int64_t EncodedReg;
4988 if (getParser().parseAbsoluteExpression(EncodedReg))
4989 return true;
4990
4991
4992
4993 RegNo = MCRegister();
4994 for (MCPhysReg Reg : X86MCRegisterClasses[RegClassID]) {
4995 if (MRI->getEncodingValue(Reg) == EncodedReg) {
4996 RegNo = Reg;
4997 break;
4998 }
4999 }
5000 if (!RegNo) {
5001 return Error(startLoc,
5002 "incorrect register number for use with this directive");
5003 }
5004 }
5005
5006 return false;
5007}
5008
5009bool X86AsmParser::parseDirectiveSEHPushReg(SMLoc Loc) {
5010 MCRegister Reg;
5011 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg))
5012 return true;
5013
5015 return TokError("expected end of directive");
5016
5017 getParser().Lex();
5018 getStreamer().emitWinCFIPushReg(Reg, Loc);
5019 return false;
5020}
5021
5022bool X86AsmParser::parseDirectiveSEHSetFrame(SMLoc Loc) {
5023 MCRegister Reg;
5024 int64_t Off;
5025 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg))
5026 return true;
5028 return TokError("you must specify a stack pointer offset");
5029
5030 getParser().Lex();
5031 if (getParser().parseAbsoluteExpression(Off))
5032 return true;
5033
5035 return TokError("expected end of directive");
5036
5037 getParser().Lex();
5038 getStreamer().emitWinCFISetFrame(Reg, Off, Loc);
5039 return false;
5040}
5041
5042bool X86AsmParser::parseDirectiveSEHSaveReg(SMLoc Loc) {
5043 MCRegister Reg;
5044 int64_t Off;
5045 if (parseSEHRegisterNumber(X86::GR64RegClassID, Reg))
5046 return true;
5048 return TokError("you must specify an offset on the stack");
5049
5050 getParser().Lex();
5051 if (getParser().parseAbsoluteExpression(Off))
5052 return true;
5053
5055 return TokError("expected end of directive");
5056
5057 getParser().Lex();
5058 getStreamer().emitWinCFISaveReg(Reg, Off, Loc);
5059 return false;
5060}
5061
5062bool X86AsmParser::parseDirectiveSEHSaveXMM(SMLoc Loc) {
5063 MCRegister Reg;
5064 int64_t Off;
5065 if (parseSEHRegisterNumber(X86::VR128XRegClassID, Reg))
5066 return true;
5068 return TokError("you must specify an offset on the stack");
5069
5070 getParser().Lex();
5071 if (getParser().parseAbsoluteExpression(Off))
5072 return true;
5073
5075 return TokError("expected end of directive");
5076
5077 getParser().Lex();
5078 getStreamer().emitWinCFISaveXMM(Reg, Off, Loc);
5079 return false;
5080}
5081
5082bool X86AsmParser::parseDirectiveSEHPushFrame(SMLoc Loc) {
5083 bool Code = false;
5084 StringRef CodeID;
5086 SMLoc startLoc = getLexer().getLoc();
5087 getParser().Lex();
5088 if (!getParser().parseIdentifier(CodeID)) {
5089 if (CodeID != "code")
5090 return Error(startLoc, "expected @code");
5091 Code = true;
5092 }
5093 }
5094
5096 return TokError("expected end of directive");
5097
5098 getParser().Lex();
5099 getStreamer().emitWinCFIPushFrame(Code, Loc);
5100 return false;
5101}
5102
5103
5108
5109#define GET_MATCHER_IMPLEMENTATION
5110#include "X86GenAsmMatcher.inc"
unsigned const MachineRegisterInfo * MRI
static MCRegister MatchRegisterName(StringRef Name)
static const char * getSubtargetFeatureName(uint64_t Val)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
Function Alias Analysis false
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
amode Optimize addressing mode
Value * getPointer(Value *Ptr)
static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb)
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool IsVCMP(unsigned Opcode)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
OptimizedStructLayoutField Field
static StringRef getName(Value *V)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallString class.
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static SymbolRef::Type getType(const Symbol *Sym)
#define LLVM_C_ABI
LLVM_C_ABI is the export/visibility macro used to mark symbols declared in llvm-c as exported when bu...
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)
Definition X86AsmParser.cpp:56
LLVM_C_ABI void LLVMInitializeX86AsmParser()
Definition X86AsmParser.cpp:5104
static bool convertSSEToAVX(MCInst &Inst)
Definition X86AsmParser.cpp:3820
static unsigned getPrefixes(OperandVector &Operands)
Definition X86AsmParser.cpp:4184
static bool CheckBaseRegAndIndexRegAndScale(MCRegister BaseReg, MCRegister IndexReg, unsigned Scale, bool Is64BitMode, StringRef &ErrMsg)
Definition X86AsmParser.cpp:1329
#define FROM_TO(FROM, TO)
uint16_t RegSizeInBits(const MCRegisterInfo &MRI, MCRegister RegNo)
Definition X86AsmParser.cpp:2610
static unsigned getSize(unsigned Kind)
uint64_t getZExtValue() const
Get zero extended value.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
void UnLex(AsmToken const &Token)
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
TokenKind getKind() const
LLVM_ABI SMLoc getEndLoc() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
constexpr size_t size() const
bool Error(SMLoc L, const Twine &Msg, SMRange Range={})
Return an error at the location L, with the message Msg.
bool parseIntToken(int64_t &V, const Twine &ErrMsg="expected integer")
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool isParsingMasm() const
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.
virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc, AsmTypeInfo *TypeInfo=nullptr)=0
Parse a primary expression.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
bool TokError(const Twine &Msg, SMRange Range={})
Report an error at the current lexer location.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
virtual bool lookUpType(StringRef Name, AsmTypeInfo &Info) const
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
bool parseTokenLoc(SMLoc &Loc)
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
@ SymbolRef
References to labels and assigned expressions.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getFlags() const
unsigned getOpcode() const
void setFlags(unsigned F)
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
bool mayLoad() const
Return true if this instruction could possibly read memory.
bool isCall() const
Return true if the instruction is a call.
bool isTerminator() const
Returns true if this instruction part of the terminator for a basic block.
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
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.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
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, SMLoc Loc=SMLoc())
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
StringRef getName() const
getName - Get the symbol name.
bool isVariable() const
isVariable - Check if this is a variable symbol.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
static constexpr StatusTy Failure
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
constexpr bool isValid() const
void push_back(const T &Elt)
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
static constexpr size_t npos
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
LLVM_ABI std::string upper() const
Convert the given ASCII string to uppercase.
char back() const
back - Get the last character in the string.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
LLVM_ABI std::string lower() const
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
bool equals_insensitive(StringRef RHS) const
Check for string equality, ignoring case.
static const char * getRegisterName(MCRegister Reg)
static const X86MCExpr * create(MCRegister Reg, MCContext &Ctx)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
std::variant< std::monostate, Loc::Single, Loc::Multi, Loc::MMI, Loc::EntryValue > Variant
Alias for the std::variant specialization base class of DbgVariable.
@ CE
Windows NT (Windows on ARM)
@ X86
Windows x64, Windows Itanium (IA-64)
bool isX86_64NonExtLowByteReg(MCRegister Reg)
@ EVEX
EVEX - Specifies that this instruction use EVEX form which provides syntax support up to 32 512-bit r...
@ VEX
VEX - encoding using 0xC4/0xC5.
@ XOP
XOP - Opcode prefix used by XOP instructions.
@ ExplicitVEXPrefix
For instructions that use VEX encoding only when {vex}, {vex2} or {vex3} is present.
bool canUseApxExtendedReg(const MCInstrDesc &Desc)
bool isX86_64ExtendedReg(MCRegister Reg)
bool isApxExtendedReg(MCRegister Reg)
void emitInstruction(MCObjectStreamer &, const MCInst &Inst, const MCSubtargetInfo &STI)
bool optimizeShiftRotateWithImmediateOne(MCInst &MI)
bool optimizeInstFromVEX3ToVEX2(MCInst &MI, const MCInstrDesc &Desc)
NodeAddr< CodeNode * > Code
Context & getContext() const
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
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.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
MCRegister getX86SubSuperRegister(MCRegister Reg, unsigned Size, bool High=false)
Target & getTheX86_32Target()
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
FunctionAddr VTableAddr Next
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...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Target & getTheX86_64Target()
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool isKind(IdKind kind) const
SmallVectorImpl< AsmRewrite > * AsmRewrites
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
X86Operand - Instances of this class represent a parsed X86 machine instruction.
SMLoc getStartLoc() const override
getStartLoc - Get the location of the first token of this operand.
bool isImm() const override
isImm - Is this an immediate operand?
static std::unique_ptr< X86Operand > CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc, StringRef SymName=StringRef(), void *OpDecl=nullptr, bool GlobalRef=true)
static std::unique_ptr< X86Operand > CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc)
static std::unique_ptr< X86Operand > CreateDXReg(SMLoc StartLoc, SMLoc EndLoc)
static std::unique_ptr< X86Operand > CreateReg(MCRegister Reg, SMLoc StartLoc, SMLoc EndLoc, bool AddressOf=false, SMLoc OffsetOfLoc=SMLoc(), StringRef SymName=StringRef(), void *OpDecl=nullptr)
SMRange getLocRange() const
getLocRange - Get the range between the first and last token of this operand.
SMLoc getEndLoc() const override
getEndLoc - Get the location of the last token of this operand.
bool isReg() const override
isReg - Is this a register operand?
bool isMem() const override
isMem - Is this a memory operand?
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.
static std::unique_ptr< X86Operand > CreateToken(StringRef Str, SMLoc Loc)
bool isMemUnsized() const
const MCExpr * getImm() const
unsigned getMemFrontendSize() const
MCRegister getReg() const override