1 //===-- X86AsmParser.cpp - Parse X86 assembly to MCInst instructions ------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/X86BaseInfo.h"
11 #include "llvm/ADT/APFloat.h"
12 #include "llvm/ADT/SmallString.h"
13 #include "llvm/ADT/SmallVector.h"
14 #include "llvm/ADT/StringSwitch.h"
15 #include "llvm/ADT/Twine.h"
16 #include "llvm/MC/MCExpr.h"
17 #include "llvm/MC/MCInst.h"
18 #include "llvm/MC/MCParser/MCAsmLexer.h"
19 #include "llvm/MC/MCParser/MCAsmParser.h"
20 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
21 #include "llvm/MC/MCRegisterInfo.h"
22 #include "llvm/MC/MCStreamer.h"
23 #include "llvm/MC/MCSubtargetInfo.h"
24 #include "llvm/MC/MCSymbol.h"
25 #include "llvm/MC/MCTargetAsmParser.h"
26 #include "llvm/Support/SourceMgr.h"
27 #include "llvm/Support/TargetRegistry.h"
28 #include "llvm/Support/raw_ostream.h"
35 class X86AsmParser : public MCTargetAsmParser {
38 ParseInstructionInfo *InstInfo;
40 MCAsmParser &getParser() const { return Parser; }
42 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
44 bool Error(SMLoc L, const Twine &Msg,
45 ArrayRef<SMRange> Ranges = ArrayRef<SMRange>(),
46 bool MatchingInlineAsm = false) {
47 if (MatchingInlineAsm) return true;
48 return Parser.Error(L, Msg, Ranges);
51 X86Operand *ErrorOperand(SMLoc Loc, StringRef Msg) {
56 X86Operand *ParseOperand();
57 X86Operand *ParseATTOperand();
58 X86Operand *ParseIntelOperand();
59 X86Operand *ParseIntelOffsetOfOperator(SMLoc StartLoc);
60 X86Operand *ParseIntelOperator(SMLoc StartLoc, unsigned OpKind);
61 X86Operand *ParseIntelMemOperand(unsigned SegReg, SMLoc StartLoc);
62 X86Operand *ParseIntelBracExpression(unsigned SegReg, unsigned Size);
63 X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
65 X86Operand *CreateMemForInlineAsm(const MCExpr *Disp, SMLoc Start, SMLoc End,
66 SMLoc SizeDirLoc, unsigned Size);
68 bool ParseIntelDotOperator(const MCExpr *Disp, const MCExpr **NewDisp,
69 SmallString<64> &Err);
71 bool ParseDirectiveWord(unsigned Size, SMLoc L);
72 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
74 bool processInstruction(MCInst &Inst,
75 const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
77 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
78 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
79 MCStreamer &Out, unsigned &ErrorInfo,
80 bool MatchingInlineAsm);
82 /// isSrcOp - Returns true if operand is either (%rsi) or %ds:%(rsi)
83 /// in 64bit mode or (%esi) or %es:(%esi) in 32bit mode.
84 bool isSrcOp(X86Operand &Op);
86 /// isDstOp - Returns true if operand is either (%rdi) or %es:(%rdi)
87 /// in 64bit mode or (%edi) or %es:(%edi) in 32bit mode.
88 bool isDstOp(X86Operand &Op);
90 bool is64BitMode() const {
91 // FIXME: Can tablegen auto-generate this?
92 return (STI.getFeatureBits() & X86::Mode64Bit) != 0;
95 unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(X86::Mode64Bit));
96 setAvailableFeatures(FB);
99 /// @name Auto-generated Matcher Functions
102 #define GET_ASSEMBLER_HEADER
103 #include "X86GenAsmMatcher.inc"
108 X86AsmParser(MCSubtargetInfo &sti, MCAsmParser &parser)
109 : MCTargetAsmParser(), STI(sti), Parser(parser), InstInfo(0) {
111 // Initialize the set of available features.
112 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
114 virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
116 virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
118 SmallVectorImpl<MCParsedAsmOperand*> &Operands);
120 virtual bool ParseDirective(AsmToken DirectiveID);
122 bool isParsingIntelSyntax() {
123 return getParser().getAssemblerDialect();
126 } // end anonymous namespace
128 /// @name Auto-generated Match Functions
131 static unsigned MatchRegisterName(StringRef Name);
135 static bool isImmSExti16i8Value(uint64_t Value) {
136 return (( Value <= 0x000000000000007FULL)||
137 (0x000000000000FF80ULL <= Value && Value <= 0x000000000000FFFFULL)||
138 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
141 static bool isImmSExti32i8Value(uint64_t Value) {
142 return (( Value <= 0x000000000000007FULL)||
143 (0x00000000FFFFFF80ULL <= Value && Value <= 0x00000000FFFFFFFFULL)||
144 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
147 static bool isImmZExtu32u8Value(uint64_t Value) {
148 return (Value <= 0x00000000000000FFULL);
151 static bool isImmSExti64i8Value(uint64_t Value) {
152 return (( Value <= 0x000000000000007FULL)||
153 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
156 static bool isImmSExti64i32Value(uint64_t Value) {
157 return (( Value <= 0x000000007FFFFFFFULL)||
158 (0xFFFFFFFF80000000ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
162 /// X86Operand - Instances of this class represent a parsed X86 machine
164 struct X86Operand : public MCParsedAsmOperand {
172 SMLoc StartLoc, EndLoc;
205 X86Operand(KindTy K, SMLoc Start, SMLoc End)
206 : Kind(K), StartLoc(Start), EndLoc(End) {}
208 /// getStartLoc - Get the location of the first token of this operand.
209 SMLoc getStartLoc() const { return StartLoc; }
210 /// getEndLoc - Get the location of the last token of this operand.
211 SMLoc getEndLoc() const { return EndLoc; }
212 /// getLocRange - Get the range between the first and last token of this
214 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
215 /// getOffsetOfLoc - Get the location of the offset operator.
216 SMLoc getOffsetOfLoc() const { return OffsetOfLoc; }
218 virtual void print(raw_ostream &OS) const {}
220 StringRef getToken() const {
221 assert(Kind == Token && "Invalid access!");
222 return StringRef(Tok.Data, Tok.Length);
224 void setTokenValue(StringRef Value) {
225 assert(Kind == Token && "Invalid access!");
226 Tok.Data = Value.data();
227 Tok.Length = Value.size();
230 unsigned getReg() const {
231 assert(Kind == Register && "Invalid access!");
235 const MCExpr *getImm() const {
236 assert(Kind == Immediate && "Invalid access!");
240 const MCExpr *getMemDisp() const {
241 assert(Kind == Memory && "Invalid access!");
244 unsigned getMemSegReg() const {
245 assert(Kind == Memory && "Invalid access!");
248 unsigned getMemBaseReg() const {
249 assert(Kind == Memory && "Invalid access!");
252 unsigned getMemIndexReg() const {
253 assert(Kind == Memory && "Invalid access!");
256 unsigned getMemScale() const {
257 assert(Kind == Memory && "Invalid access!");
261 bool isToken() const {return Kind == Token; }
263 bool isImm() const { return Kind == Immediate; }
265 bool isImmSExti16i8() const {
269 // If this isn't a constant expr, just assume it fits and let relaxation
271 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
275 // Otherwise, check the value is in a range that makes sense for this
277 return isImmSExti16i8Value(CE->getValue());
279 bool isImmSExti32i8() const {
283 // If this isn't a constant expr, just assume it fits and let relaxation
285 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
289 // Otherwise, check the value is in a range that makes sense for this
291 return isImmSExti32i8Value(CE->getValue());
293 bool isImmZExtu32u8() const {
297 // If this isn't a constant expr, just assume it fits and let relaxation
299 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
303 // Otherwise, check the value is in a range that makes sense for this
305 return isImmZExtu32u8Value(CE->getValue());
307 bool isImmSExti64i8() const {
311 // If this isn't a constant expr, just assume it fits and let relaxation
313 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
317 // Otherwise, check the value is in a range that makes sense for this
319 return isImmSExti64i8Value(CE->getValue());
321 bool isImmSExti64i32() const {
325 // If this isn't a constant expr, just assume it fits and let relaxation
327 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
331 // Otherwise, check the value is in a range that makes sense for this
333 return isImmSExti64i32Value(CE->getValue());
336 bool isOffsetOf() const {
337 return OffsetOfLoc.getPointer();
340 bool needAddressOf() const {
344 bool isMem() const { return Kind == Memory; }
345 bool isMem8() const {
346 return Kind == Memory && (!Mem.Size || Mem.Size == 8);
348 bool isMem16() const {
349 return Kind == Memory && (!Mem.Size || Mem.Size == 16);
351 bool isMem32() const {
352 return Kind == Memory && (!Mem.Size || Mem.Size == 32);
354 bool isMem64() const {
355 return Kind == Memory && (!Mem.Size || Mem.Size == 64);
357 bool isMem80() const {
358 return Kind == Memory && (!Mem.Size || Mem.Size == 80);
360 bool isMem128() const {
361 return Kind == Memory && (!Mem.Size || Mem.Size == 128);
363 bool isMem256() const {
364 return Kind == Memory && (!Mem.Size || Mem.Size == 256);
367 bool isMemVX32() const {
368 return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
369 getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
371 bool isMemVY32() const {
372 return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
373 getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
375 bool isMemVX64() const {
376 return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
377 getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
379 bool isMemVY64() const {
380 return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
381 getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
384 bool isAbsMem() const {
385 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
386 !getMemIndexReg() && getMemScale() == 1;
389 bool isReg() const { return Kind == Register; }
391 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
392 // Add as immediates when possible.
393 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
394 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
396 Inst.addOperand(MCOperand::CreateExpr(Expr));
399 void addRegOperands(MCInst &Inst, unsigned N) const {
400 assert(N == 1 && "Invalid number of operands!");
401 Inst.addOperand(MCOperand::CreateReg(getReg()));
404 void addImmOperands(MCInst &Inst, unsigned N) const {
405 assert(N == 1 && "Invalid number of operands!");
406 addExpr(Inst, getImm());
409 void addMem8Operands(MCInst &Inst, unsigned N) const {
410 addMemOperands(Inst, N);
412 void addMem16Operands(MCInst &Inst, unsigned N) const {
413 addMemOperands(Inst, N);
415 void addMem32Operands(MCInst &Inst, unsigned N) const {
416 addMemOperands(Inst, N);
418 void addMem64Operands(MCInst &Inst, unsigned N) const {
419 addMemOperands(Inst, N);
421 void addMem80Operands(MCInst &Inst, unsigned N) const {
422 addMemOperands(Inst, N);
424 void addMem128Operands(MCInst &Inst, unsigned N) const {
425 addMemOperands(Inst, N);
427 void addMem256Operands(MCInst &Inst, unsigned N) const {
428 addMemOperands(Inst, N);
430 void addMemVX32Operands(MCInst &Inst, unsigned N) const {
431 addMemOperands(Inst, N);
433 void addMemVY32Operands(MCInst &Inst, unsigned N) const {
434 addMemOperands(Inst, N);
436 void addMemVX64Operands(MCInst &Inst, unsigned N) const {
437 addMemOperands(Inst, N);
439 void addMemVY64Operands(MCInst &Inst, unsigned N) const {
440 addMemOperands(Inst, N);
443 void addMemOperands(MCInst &Inst, unsigned N) const {
444 assert((N == 5) && "Invalid number of operands!");
445 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
446 Inst.addOperand(MCOperand::CreateImm(getMemScale()));
447 Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
448 addExpr(Inst, getMemDisp());
449 Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
452 void addAbsMemOperands(MCInst &Inst, unsigned N) const {
453 assert((N == 1) && "Invalid number of operands!");
454 // Add as immediates when possible.
455 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
456 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
458 Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
461 static X86Operand *CreateToken(StringRef Str, SMLoc Loc) {
462 SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
463 X86Operand *Res = new X86Operand(Token, Loc, EndLoc);
464 Res->Tok.Data = Str.data();
465 Res->Tok.Length = Str.size();
469 static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
470 bool AddressOf = false,
471 SMLoc OffsetOfLoc = SMLoc()) {
472 X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc);
473 Res->Reg.RegNo = RegNo;
474 Res->AddressOf = AddressOf;
475 Res->OffsetOfLoc = OffsetOfLoc;
479 static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc){
480 X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc);
485 /// Create an absolute memory operand.
486 static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
488 X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
490 Res->Mem.Disp = Disp;
491 Res->Mem.BaseReg = 0;
492 Res->Mem.IndexReg = 0;
494 Res->Mem.Size = Size;
495 Res->AddressOf = false;
499 /// Create a generalized memory operand.
500 static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp,
501 unsigned BaseReg, unsigned IndexReg,
502 unsigned Scale, SMLoc StartLoc, SMLoc EndLoc,
504 // We should never just have a displacement, that should be parsed as an
505 // absolute memory operand.
506 assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
508 // The scale should always be one of {1,2,4,8}.
509 assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
511 X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
512 Res->Mem.SegReg = SegReg;
513 Res->Mem.Disp = Disp;
514 Res->Mem.BaseReg = BaseReg;
515 Res->Mem.IndexReg = IndexReg;
516 Res->Mem.Scale = Scale;
517 Res->Mem.Size = Size;
518 Res->AddressOf = false;
523 } // end anonymous namespace.
525 bool X86AsmParser::isSrcOp(X86Operand &Op) {
526 unsigned basereg = is64BitMode() ? X86::RSI : X86::ESI;
528 return (Op.isMem() &&
529 (Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::DS) &&
530 isa<MCConstantExpr>(Op.Mem.Disp) &&
531 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
532 Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0);
535 bool X86AsmParser::isDstOp(X86Operand &Op) {
536 unsigned basereg = is64BitMode() ? X86::RDI : X86::EDI;
539 (Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::ES) &&
540 isa<MCConstantExpr>(Op.Mem.Disp) &&
541 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
542 Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0;
545 bool X86AsmParser::ParseRegister(unsigned &RegNo,
546 SMLoc &StartLoc, SMLoc &EndLoc) {
548 const AsmToken &PercentTok = Parser.getTok();
549 StartLoc = PercentTok.getLoc();
551 // If we encounter a %, ignore it. This code handles registers with and
552 // without the prefix, unprefixed registers can occur in cfi directives.
553 if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent))
554 Parser.Lex(); // Eat percent token.
556 const AsmToken &Tok = Parser.getTok();
557 EndLoc = Tok.getEndLoc();
559 if (Tok.isNot(AsmToken::Identifier)) {
560 if (isParsingIntelSyntax()) return true;
561 return Error(StartLoc, "invalid register name",
562 SMRange(StartLoc, EndLoc));
565 RegNo = MatchRegisterName(Tok.getString());
567 // If the match failed, try the register name as lowercase.
569 RegNo = MatchRegisterName(Tok.getString().lower());
571 if (!is64BitMode()) {
572 // FIXME: This should be done using Requires<In32BitMode> and
573 // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also
575 // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a
577 if (RegNo == X86::RIZ ||
578 X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||
579 X86II::isX86_64NonExtLowByteReg(RegNo) ||
580 X86II::isX86_64ExtendedReg(RegNo))
581 return Error(StartLoc, "register %"
582 + Tok.getString() + " is only available in 64-bit mode",
583 SMRange(StartLoc, EndLoc));
586 // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
587 if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) {
589 Parser.Lex(); // Eat 'st'
591 // Check to see if we have '(4)' after %st.
592 if (getLexer().isNot(AsmToken::LParen))
597 const AsmToken &IntTok = Parser.getTok();
598 if (IntTok.isNot(AsmToken::Integer))
599 return Error(IntTok.getLoc(), "expected stack index");
600 switch (IntTok.getIntVal()) {
601 case 0: RegNo = X86::ST0; break;
602 case 1: RegNo = X86::ST1; break;
603 case 2: RegNo = X86::ST2; break;
604 case 3: RegNo = X86::ST3; break;
605 case 4: RegNo = X86::ST4; break;
606 case 5: RegNo = X86::ST5; break;
607 case 6: RegNo = X86::ST6; break;
608 case 7: RegNo = X86::ST7; break;
609 default: return Error(IntTok.getLoc(), "invalid stack index");
612 if (getParser().Lex().isNot(AsmToken::RParen))
613 return Error(Parser.getTok().getLoc(), "expected ')'");
615 EndLoc = Parser.getTok().getEndLoc();
616 Parser.Lex(); // Eat ')'
620 EndLoc = Parser.getTok().getEndLoc();
622 // If this is "db[0-7]", match it as an alias
624 if (RegNo == 0 && Tok.getString().size() == 3 &&
625 Tok.getString().startswith("db")) {
626 switch (Tok.getString()[2]) {
627 case '0': RegNo = X86::DR0; break;
628 case '1': RegNo = X86::DR1; break;
629 case '2': RegNo = X86::DR2; break;
630 case '3': RegNo = X86::DR3; break;
631 case '4': RegNo = X86::DR4; break;
632 case '5': RegNo = X86::DR5; break;
633 case '6': RegNo = X86::DR6; break;
634 case '7': RegNo = X86::DR7; break;
638 EndLoc = Parser.getTok().getEndLoc();
639 Parser.Lex(); // Eat it.
645 if (isParsingIntelSyntax()) return true;
646 return Error(StartLoc, "invalid register name",
647 SMRange(StartLoc, EndLoc));
650 Parser.Lex(); // Eat identifier token.
654 X86Operand *X86AsmParser::ParseOperand() {
655 if (isParsingIntelSyntax())
656 return ParseIntelOperand();
657 return ParseATTOperand();
660 /// getIntelMemOperandSize - Return intel memory operand size.
661 static unsigned getIntelMemOperandSize(StringRef OpStr) {
662 unsigned Size = StringSwitch<unsigned>(OpStr)
663 .Cases("BYTE", "byte", 8)
664 .Cases("WORD", "word", 16)
665 .Cases("DWORD", "dword", 32)
666 .Cases("QWORD", "qword", 64)
667 .Cases("XWORD", "xword", 80)
668 .Cases("XMMWORD", "xmmword", 128)
669 .Cases("YMMWORD", "ymmword", 256)
674 enum IntelBracExprState {
680 IBES_REGISTER_STAR_INTEGER,
690 class IntelBracExprStateMachine {
691 IntelBracExprState State;
692 unsigned BaseReg, IndexReg, Scale;
701 IntelBracExprStateMachine(MCAsmParser &parser) :
702 State(IBES_START), BaseReg(0), IndexReg(0), Scale(1), Disp(0),
703 TmpReg(0), TmpInteger(0), isPlus(true) {}
705 unsigned getBaseReg() { return BaseReg; }
706 unsigned getIndexReg() { return IndexReg; }
707 unsigned getScale() { return Scale; }
708 int64_t getDisp() { return Disp; }
709 bool isValidEndState() { return State == IBES_RBRAC; }
725 // If we already have a BaseReg, then assume this is the IndexReg with a
730 assert (!IndexReg && "BaseReg/IndexReg already set!");
735 case IBES_INDEX_REGISTER:
758 // If we already have a BaseReg, then assume this is the IndexReg with a
763 assert (!IndexReg && "BaseReg/IndexReg already set!");
768 case IBES_INDEX_REGISTER:
774 void onRegister(unsigned Reg) {
780 State = IBES_REGISTER;
783 case IBES_INTEGER_STAR:
784 assert (!IndexReg && "IndexReg already set!");
785 State = IBES_INDEX_REGISTER;
797 State = IBES_DISP_EXPR;
801 void onInteger(int64_t TmpInt) {
807 State = IBES_INTEGER;
811 State = IBES_INTEGER;
814 case IBES_REGISTER_STAR:
815 assert (!IndexReg && "IndexReg already set!");
816 State = IBES_INDEX_REGISTER;
828 State = IBES_INTEGER_STAR;
831 State = IBES_REGISTER_STAR;
863 // If we already have a BaseReg, then assume this is the IndexReg with a
868 assert (!IndexReg && "BaseReg/IndexReg already set!");
873 case IBES_INDEX_REGISTER:
880 X86Operand *X86AsmParser::CreateMemForInlineAsm(const MCExpr *Disp, SMLoc Start,
881 SMLoc End, SMLoc SizeDirLoc,
883 bool NeedSizeDir = false;
884 bool IsVarDecl = false;
885 if (const MCSymbolRefExpr *SymRef = dyn_cast<MCSymbolRefExpr>(Disp)) {
886 const MCSymbol &Sym = SymRef->getSymbol();
887 // FIXME: The SemaLookup will fail if the name is anything other then an
889 // FIXME: Pass a valid SMLoc.
890 unsigned tLength, tSize, tType;
891 SemaCallback->LookupInlineAsmIdentifier(Sym.getName(), NULL, tLength,
892 tSize, tType, IsVarDecl);
894 Size = tType * 8; // Size is in terms of bits in this context.
895 NeedSizeDir = Size > 0;
899 // If this is not a VarDecl then assume it is a FuncDecl or some other label
900 // reference. We need an 'r' constraint here, so we need to create register
901 // operand to ensure proper matching. Just pick a GPR based on the size of
904 unsigned RegNo = is64BitMode() ? X86::RBX : X86::EBX;
905 return X86Operand::CreateReg(RegNo, Start, End, /*AddressOf=*/true);
909 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_SizeDirective, SizeDirLoc,
912 // When parsing inline assembly we set the base register to a non-zero value
913 // as we don't know the actual value at this time. This is necessary to
914 // get the matching correct in some cases.
915 return X86Operand::CreateMem(/*SegReg*/0, Disp, /*BaseReg*/1, /*IndexReg*/0,
916 /*Scale*/1, Start, End, Size);
919 X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
921 const AsmToken &Tok = Parser.getTok();
922 SMLoc Start = Tok.getLoc(), End = Tok.getEndLoc();
925 if (getLexer().isNot(AsmToken::LBrac))
926 return ErrorOperand(Start, "Expected '[' token!");
931 // Try to handle '[' 'symbol' ']'
932 if (getLexer().is(AsmToken::Identifier)) {
933 if (ParseRegister(TmpReg, Start, End)) {
935 if (getParser().parseExpression(Disp, End))
938 if (getLexer().isNot(AsmToken::RBrac))
939 return ErrorOperand(Parser.getTok().getLoc(), "Expected ']' token!");
940 // Adjust the EndLoc due to the ']'.
941 End = SMLoc::getFromPointer(Parser.getTok().getEndLoc().getPointer()-1);
943 if (!isParsingInlineAsm())
944 return X86Operand::CreateMem(Disp, Start, End, Size);
946 // We want the size directive before the '['.
947 SMLoc SizeDirLoc = SMLoc::getFromPointer(Start.getPointer()-1);
948 return CreateMemForInlineAsm(Disp, Start, End, SizeDirLoc, Size);
952 // Parse [ BaseReg + Scale*IndexReg + Disp ].
954 IntelBracExprStateMachine SM(Parser);
956 // If we parsed a register, then the end loc has already been set and
957 // the identifier has already been lexed. We also need to update the
960 SM.onRegister(TmpReg);
962 const MCExpr *Disp = 0;
964 bool UpdateLocLex = true;
966 // The period in the dot operator (e.g., [ebx].foo.bar) is parsed as an
967 // identifier. Don't try an parse it as a register.
968 if (Tok.getString().startswith("."))
971 switch (getLexer().getKind()) {
973 if (SM.isValidEndState()) {
977 return ErrorOperand(Tok.getLoc(), "Unexpected token!");
979 case AsmToken::Identifier: {
980 // This could be a register or a displacement expression.
981 if(!ParseRegister(TmpReg, Start, End)) {
982 SM.onRegister(TmpReg);
983 UpdateLocLex = false;
985 } else if (!getParser().parseExpression(Disp, End)) {
987 UpdateLocLex = false;
990 return ErrorOperand(Tok.getLoc(), "Unexpected identifier!");
992 case AsmToken::Integer: {
993 int64_t Val = Tok.getIntVal();
997 case AsmToken::Plus: SM.onPlus(); break;
998 case AsmToken::Minus: SM.onMinus(); break;
999 case AsmToken::Star: SM.onStar(); break;
1000 case AsmToken::LBrac: SM.onLBrac(); break;
1001 case AsmToken::RBrac: SM.onRBrac(); break;
1003 if (!Done && UpdateLocLex) {
1005 Parser.Lex(); // Consume the token.
1010 Disp = MCConstantExpr::Create(SM.getDisp(), getContext());
1012 // Parse the dot operator (e.g., [ebx].foo.bar).
1013 if (Tok.getString().startswith(".")) {
1014 SmallString<64> Err;
1015 const MCExpr *NewDisp;
1016 if (ParseIntelDotOperator(Disp, &NewDisp, Err))
1017 return ErrorOperand(Tok.getLoc(), Err);
1019 End = Parser.getTok().getEndLoc();
1020 Parser.Lex(); // Eat the field.
1024 int BaseReg = SM.getBaseReg();
1025 int IndexReg = SM.getIndexReg();
1028 if (!BaseReg && !IndexReg) {
1030 return X86Operand::CreateMem(Disp, Start, End);
1032 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, Start, End, Size);
1035 int Scale = SM.getScale();
1036 return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
1040 /// ParseIntelMemOperand - Parse intel style memory operand.
1041 X86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg, SMLoc Start) {
1042 const AsmToken &Tok = Parser.getTok();
1045 unsigned Size = getIntelMemOperandSize(Tok.getString());
1048 assert ((Tok.getString() == "PTR" || Tok.getString() == "ptr") &&
1049 "Unexpected token!");
1053 if (getLexer().is(AsmToken::LBrac))
1054 return ParseIntelBracExpression(SegReg, Size);
1056 if (!ParseRegister(SegReg, Start, End)) {
1057 // Handel SegReg : [ ... ]
1058 if (getLexer().isNot(AsmToken::Colon))
1059 return ErrorOperand(Start, "Expected ':' token!");
1060 Parser.Lex(); // Eat :
1061 if (getLexer().isNot(AsmToken::LBrac))
1062 return ErrorOperand(Start, "Expected '[' token!");
1063 return ParseIntelBracExpression(SegReg, Size);
1066 const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
1067 if (getParser().parseExpression(Disp, End))
1070 if (!isParsingInlineAsm())
1071 return X86Operand::CreateMem(Disp, Start, End, Size);
1072 return CreateMemForInlineAsm(Disp, Start, End, Start, Size);
1075 /// Parse the '.' operator.
1076 bool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp,
1077 const MCExpr **NewDisp,
1078 SmallString<64> &Err) {
1079 AsmToken Tok = *&Parser.getTok();
1080 uint64_t OrigDispVal, DotDispVal;
1082 // FIXME: Handle non-constant expressions.
1083 if (const MCConstantExpr *OrigDisp = dyn_cast<MCConstantExpr>(Disp)) {
1084 OrigDispVal = OrigDisp->getValue();
1086 Err = "Non-constant offsets are not supported!";
1091 StringRef DotDispStr = Tok.getString().drop_front(1);
1093 // .Imm gets lexed as a real.
1094 if (Tok.is(AsmToken::Real)) {
1096 DotDispStr.getAsInteger(10, DotDisp);
1097 DotDispVal = DotDisp.getZExtValue();
1098 } else if (Tok.is(AsmToken::Identifier)) {
1099 // We should only see an identifier when parsing the original inline asm.
1100 // The front-end should rewrite this in terms of immediates.
1101 assert (isParsingInlineAsm() && "Unexpected field name!");
1104 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
1105 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1107 Err = "Unable to lookup field reference!";
1110 DotDispVal = DotDisp;
1112 Err = "Unexpected token type!";
1116 if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1117 SMLoc Loc = SMLoc::getFromPointer(DotDispStr.data());
1118 unsigned Len = DotDispStr.size();
1119 unsigned Val = OrigDispVal + DotDispVal;
1120 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_DotOperator, Loc, Len,
1124 *NewDisp = MCConstantExpr::Create(OrigDispVal + DotDispVal, getContext());
1128 /// Parse the 'offset' operator. This operator is used to specify the
1129 /// location rather then the content of a variable.
1130 X86Operand *X86AsmParser::ParseIntelOffsetOfOperator(SMLoc Start) {
1131 SMLoc OffsetOfLoc = Start;
1132 Parser.Lex(); // Eat offset.
1133 Start = Parser.getTok().getLoc();
1134 assert (Parser.getTok().is(AsmToken::Identifier) && "Expected an identifier");
1138 if (getParser().parseExpression(Val, End))
1139 return ErrorOperand(Start, "Unable to parse expression!");
1141 // Don't emit the offset operator.
1142 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Skip, OffsetOfLoc, 7));
1144 // The offset operator will have an 'r' constraint, thus we need to create
1145 // register operand to ensure proper matching. Just pick a GPR based on
1146 // the size of a pointer.
1147 unsigned RegNo = is64BitMode() ? X86::RBX : X86::EBX;
1148 return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
1152 enum IntelOperatorKind {
1158 /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator
1159 /// returns the number of elements in an array. It returns the value 1 for
1160 /// non-array variables. The SIZE operator returns the size of a C or C++
1161 /// variable. A variable's size is the product of its LENGTH and TYPE. The
1162 /// TYPE operator returns the size of a C or C++ type or variable. If the
1163 /// variable is an array, TYPE returns the size of a single element.
1164 X86Operand *X86AsmParser::ParseIntelOperator(SMLoc Start, unsigned OpKind) {
1165 SMLoc TypeLoc = Start;
1166 Parser.Lex(); // Eat offset.
1167 Start = Parser.getTok().getLoc();
1168 assert (Parser.getTok().is(AsmToken::Identifier) && "Expected an identifier");
1172 if (getParser().parseExpression(Val, End))
1175 unsigned Length = 0, Size = 0, Type = 0;
1176 if (const MCSymbolRefExpr *SymRef = dyn_cast<MCSymbolRefExpr>(Val)) {
1177 const MCSymbol &Sym = SymRef->getSymbol();
1178 // FIXME: The SemaLookup will fail if the name is anything other then an
1180 // FIXME: Pass a valid SMLoc.
1182 if (!SemaCallback->LookupInlineAsmIdentifier(Sym.getName(), NULL, Length,
1183 Size, Type, IsVarDecl))
1184 return ErrorOperand(Start, "Unable to lookup expr!");
1188 default: llvm_unreachable("Unexpected operand kind!");
1189 case IOK_LENGTH: CVal = Length; break;
1190 case IOK_SIZE: CVal = Size; break;
1191 case IOK_TYPE: CVal = Type; break;
1194 // Rewrite the type operator and the C or C++ type or variable in terms of an
1195 // immediate. E.g. TYPE foo -> $$4
1196 unsigned Len = End.getPointer() - TypeLoc.getPointer();
1197 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Imm, TypeLoc, Len, CVal));
1199 const MCExpr *Imm = MCConstantExpr::Create(CVal, getContext());
1200 return X86Operand::CreateImm(Imm, Start, End);
1203 X86Operand *X86AsmParser::ParseIntelOperand() {
1204 SMLoc Start = Parser.getTok().getLoc(), End;
1205 StringRef AsmTokStr = Parser.getTok().getString();
1207 // Offset, length, type and size operators.
1208 if (isParsingInlineAsm()) {
1209 if (AsmTokStr == "offset" || AsmTokStr == "OFFSET")
1210 return ParseIntelOffsetOfOperator(Start);
1211 if (AsmTokStr == "length" || AsmTokStr == "LENGTH")
1212 return ParseIntelOperator(Start, IOK_LENGTH);
1213 if (AsmTokStr == "size" || AsmTokStr == "SIZE")
1214 return ParseIntelOperator(Start, IOK_SIZE);
1215 if (AsmTokStr == "type" || AsmTokStr == "TYPE")
1216 return ParseIntelOperator(Start, IOK_TYPE);
1220 if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Real) ||
1221 getLexer().is(AsmToken::Minus)) {
1223 if (!getParser().parseExpression(Val, End)) {
1224 if (isParsingInlineAsm())
1225 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix, Start));
1226 return X86Operand::CreateImm(Val, Start, End);
1232 if (!ParseRegister(RegNo, Start, End)) {
1233 // If this is a segment register followed by a ':', then this is the start
1234 // of a memory reference, otherwise this is a normal register reference.
1235 if (getLexer().isNot(AsmToken::Colon))
1236 return X86Operand::CreateReg(RegNo, Start, End);
1238 getParser().Lex(); // Eat the colon.
1239 return ParseIntelMemOperand(RegNo, Start);
1243 return ParseIntelMemOperand(0, Start);
1246 X86Operand *X86AsmParser::ParseATTOperand() {
1247 switch (getLexer().getKind()) {
1249 // Parse a memory operand with no segment register.
1250 return ParseMemOperand(0, Parser.getTok().getLoc());
1251 case AsmToken::Percent: {
1252 // Read the register.
1255 if (ParseRegister(RegNo, Start, End)) return 0;
1256 if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
1257 Error(Start, "%eiz and %riz can only be used as index registers",
1258 SMRange(Start, End));
1262 // If this is a segment register followed by a ':', then this is the start
1263 // of a memory reference, otherwise this is a normal register reference.
1264 if (getLexer().isNot(AsmToken::Colon))
1265 return X86Operand::CreateReg(RegNo, Start, End);
1268 getParser().Lex(); // Eat the colon.
1269 return ParseMemOperand(RegNo, Start);
1271 case AsmToken::Dollar: {
1272 // $42 -> immediate.
1273 SMLoc Start = Parser.getTok().getLoc(), End;
1276 if (getParser().parseExpression(Val, End))
1278 return X86Operand::CreateImm(Val, Start, End);
1283 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
1284 /// has already been parsed if present.
1285 X86Operand *X86AsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) {
1287 // We have to disambiguate a parenthesized expression "(4+5)" from the start
1288 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
1289 // only way to do this without lookahead is to eat the '(' and see what is
1291 const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
1292 if (getLexer().isNot(AsmToken::LParen)) {
1294 if (getParser().parseExpression(Disp, ExprEnd)) return 0;
1296 // After parsing the base expression we could either have a parenthesized
1297 // memory address or not. If not, return now. If so, eat the (.
1298 if (getLexer().isNot(AsmToken::LParen)) {
1299 // Unless we have a segment register, treat this as an immediate.
1301 return X86Operand::CreateMem(Disp, MemStart, ExprEnd);
1302 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
1308 // Okay, we have a '('. We don't know if this is an expression or not, but
1309 // so we have to eat the ( to see beyond it.
1310 SMLoc LParenLoc = Parser.getTok().getLoc();
1311 Parser.Lex(); // Eat the '('.
1313 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
1314 // Nothing to do here, fall into the code below with the '(' part of the
1315 // memory operand consumed.
1319 // It must be an parenthesized expression, parse it now.
1320 if (getParser().parseParenExpression(Disp, ExprEnd))
1323 // After parsing the base expression we could either have a parenthesized
1324 // memory address or not. If not, return now. If so, eat the (.
1325 if (getLexer().isNot(AsmToken::LParen)) {
1326 // Unless we have a segment register, treat this as an immediate.
1328 return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd);
1329 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
1337 // If we reached here, then we just ate the ( of the memory operand. Process
1338 // the rest of the memory operand.
1339 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
1342 if (getLexer().is(AsmToken::Percent)) {
1343 SMLoc StartLoc, EndLoc;
1344 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return 0;
1345 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
1346 Error(StartLoc, "eiz and riz can only be used as index registers",
1347 SMRange(StartLoc, EndLoc));
1352 if (getLexer().is(AsmToken::Comma)) {
1353 Parser.Lex(); // Eat the comma.
1354 IndexLoc = Parser.getTok().getLoc();
1356 // Following the comma we should have either an index register, or a scale
1357 // value. We don't support the later form, but we want to parse it
1360 // Not that even though it would be completely consistent to support syntax
1361 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
1362 if (getLexer().is(AsmToken::Percent)) {
1364 if (ParseRegister(IndexReg, L, L)) return 0;
1366 if (getLexer().isNot(AsmToken::RParen)) {
1367 // Parse the scale amount:
1368 // ::= ',' [scale-expression]
1369 if (getLexer().isNot(AsmToken::Comma)) {
1370 Error(Parser.getTok().getLoc(),
1371 "expected comma in scale expression");
1374 Parser.Lex(); // Eat the comma.
1376 if (getLexer().isNot(AsmToken::RParen)) {
1377 SMLoc Loc = Parser.getTok().getLoc();
1380 if (getParser().parseAbsoluteExpression(ScaleVal)){
1381 Error(Loc, "expected scale expression");
1385 // Validate the scale amount.
1386 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){
1387 Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
1390 Scale = (unsigned)ScaleVal;
1393 } else if (getLexer().isNot(AsmToken::RParen)) {
1394 // A scale amount without an index is ignored.
1396 SMLoc Loc = Parser.getTok().getLoc();
1399 if (getParser().parseAbsoluteExpression(Value))
1403 Warning(Loc, "scale factor without index register is ignored");
1408 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
1409 if (getLexer().isNot(AsmToken::RParen)) {
1410 Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
1413 SMLoc MemEnd = Parser.getTok().getEndLoc();
1414 Parser.Lex(); // Eat the ')'.
1416 // If we have both a base register and an index register make sure they are
1417 // both 64-bit or 32-bit registers.
1418 // To support VSIB, IndexReg can be 128-bit or 256-bit registers.
1419 if (BaseReg != 0 && IndexReg != 0) {
1420 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&
1421 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
1422 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg)) &&
1423 IndexReg != X86::RIZ) {
1424 Error(IndexLoc, "index register is 32-bit, but base register is 64-bit");
1427 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) &&
1428 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
1429 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) &&
1430 IndexReg != X86::EIZ){
1431 Error(IndexLoc, "index register is 64-bit, but base register is 32-bit");
1436 return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
1441 ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
1442 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1444 StringRef PatchedName = Name;
1446 // FIXME: Hack to recognize setneb as setne.
1447 if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
1448 PatchedName != "setb" && PatchedName != "setnb")
1449 PatchedName = PatchedName.substr(0, Name.size()-1);
1451 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
1452 const MCExpr *ExtraImmOp = 0;
1453 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
1454 (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
1455 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
1456 bool IsVCMP = PatchedName[0] == 'v';
1457 unsigned SSECCIdx = IsVCMP ? 4 : 3;
1458 unsigned SSEComparisonCode = StringSwitch<unsigned>(
1459 PatchedName.slice(SSECCIdx, PatchedName.size() - 2))
1463 .Case("unord", 0x03)
1468 /* AVX only from here */
1469 .Case("eq_uq", 0x08)
1472 .Case("false", 0x0B)
1473 .Case("neq_oq", 0x0C)
1477 .Case("eq_os", 0x10)
1478 .Case("lt_oq", 0x11)
1479 .Case("le_oq", 0x12)
1480 .Case("unord_s", 0x13)
1481 .Case("neq_us", 0x14)
1482 .Case("nlt_uq", 0x15)
1483 .Case("nle_uq", 0x16)
1484 .Case("ord_s", 0x17)
1485 .Case("eq_us", 0x18)
1486 .Case("nge_uq", 0x19)
1487 .Case("ngt_uq", 0x1A)
1488 .Case("false_os", 0x1B)
1489 .Case("neq_os", 0x1C)
1490 .Case("ge_oq", 0x1D)
1491 .Case("gt_oq", 0x1E)
1492 .Case("true_us", 0x1F)
1494 if (SSEComparisonCode != ~0U && (IsVCMP || SSEComparisonCode < 8)) {
1495 ExtraImmOp = MCConstantExpr::Create(SSEComparisonCode,
1496 getParser().getContext());
1497 if (PatchedName.endswith("ss")) {
1498 PatchedName = IsVCMP ? "vcmpss" : "cmpss";
1499 } else if (PatchedName.endswith("sd")) {
1500 PatchedName = IsVCMP ? "vcmpsd" : "cmpsd";
1501 } else if (PatchedName.endswith("ps")) {
1502 PatchedName = IsVCMP ? "vcmpps" : "cmpps";
1504 assert(PatchedName.endswith("pd") && "Unexpected mnemonic!");
1505 PatchedName = IsVCMP ? "vcmppd" : "cmppd";
1510 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
1512 if (ExtraImmOp && !isParsingIntelSyntax())
1513 Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc));
1515 // Determine whether this is an instruction prefix.
1517 Name == "lock" || Name == "rep" ||
1518 Name == "repe" || Name == "repz" ||
1519 Name == "repne" || Name == "repnz" ||
1520 Name == "rex64" || Name == "data16";
1523 // This does the actual operand parsing. Don't parse any more if we have a
1524 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
1525 // just want to parse the "lock" as the first instruction and the "incl" as
1527 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
1529 // Parse '*' modifier.
1530 if (getLexer().is(AsmToken::Star)) {
1531 SMLoc Loc = Parser.getTok().getLoc();
1532 Operands.push_back(X86Operand::CreateToken("*", Loc));
1533 Parser.Lex(); // Eat the star.
1536 // Read the first operand.
1537 if (X86Operand *Op = ParseOperand())
1538 Operands.push_back(Op);
1540 Parser.eatToEndOfStatement();
1544 while (getLexer().is(AsmToken::Comma)) {
1545 Parser.Lex(); // Eat the comma.
1547 // Parse and remember the operand.
1548 if (X86Operand *Op = ParseOperand())
1549 Operands.push_back(Op);
1551 Parser.eatToEndOfStatement();
1556 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1557 SMLoc Loc = getLexer().getLoc();
1558 Parser.eatToEndOfStatement();
1559 return Error(Loc, "unexpected token in argument list");
1563 if (getLexer().is(AsmToken::EndOfStatement))
1564 Parser.Lex(); // Consume the EndOfStatement
1565 else if (isPrefix && getLexer().is(AsmToken::Slash))
1566 Parser.Lex(); // Consume the prefix separator Slash
1568 if (ExtraImmOp && isParsingIntelSyntax())
1569 Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc));
1571 // This is a terrible hack to handle "out[bwl]? %al, (%dx)" ->
1572 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
1573 // documented form in various unofficial manuals, so a lot of code uses it.
1574 if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
1575 Operands.size() == 3) {
1576 X86Operand &Op = *(X86Operand*)Operands.back();
1577 if (Op.isMem() && Op.Mem.SegReg == 0 &&
1578 isa<MCConstantExpr>(Op.Mem.Disp) &&
1579 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
1580 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
1581 SMLoc Loc = Op.getEndLoc();
1582 Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
1586 // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al".
1587 if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") &&
1588 Operands.size() == 3) {
1589 X86Operand &Op = *(X86Operand*)Operands.begin()[1];
1590 if (Op.isMem() && Op.Mem.SegReg == 0 &&
1591 isa<MCConstantExpr>(Op.Mem.Disp) &&
1592 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
1593 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
1594 SMLoc Loc = Op.getEndLoc();
1595 Operands.begin()[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
1599 // Transform "ins[bwl] %dx, %es:(%edi)" into "ins[bwl]"
1600 if (Name.startswith("ins") && Operands.size() == 3 &&
1601 (Name == "insb" || Name == "insw" || Name == "insl")) {
1602 X86Operand &Op = *(X86Operand*)Operands.begin()[1];
1603 X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
1604 if (Op.isReg() && Op.getReg() == X86::DX && isDstOp(Op2)) {
1605 Operands.pop_back();
1606 Operands.pop_back();
1612 // Transform "outs[bwl] %ds:(%esi), %dx" into "out[bwl]"
1613 if (Name.startswith("outs") && Operands.size() == 3 &&
1614 (Name == "outsb" || Name == "outsw" || Name == "outsl")) {
1615 X86Operand &Op = *(X86Operand*)Operands.begin()[1];
1616 X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
1617 if (isSrcOp(Op) && Op2.isReg() && Op2.getReg() == X86::DX) {
1618 Operands.pop_back();
1619 Operands.pop_back();
1625 // Transform "movs[bwl] %ds:(%esi), %es:(%edi)" into "movs[bwl]"
1626 if (Name.startswith("movs") && Operands.size() == 3 &&
1627 (Name == "movsb" || Name == "movsw" || Name == "movsl" ||
1628 (is64BitMode() && Name == "movsq"))) {
1629 X86Operand &Op = *(X86Operand*)Operands.begin()[1];
1630 X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
1631 if (isSrcOp(Op) && isDstOp(Op2)) {
1632 Operands.pop_back();
1633 Operands.pop_back();
1638 // Transform "lods[bwl] %ds:(%esi),{%al,%ax,%eax,%rax}" into "lods[bwl]"
1639 if (Name.startswith("lods") && Operands.size() == 3 &&
1640 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
1641 Name == "lodsl" || (is64BitMode() && Name == "lodsq"))) {
1642 X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
1643 X86Operand *Op2 = static_cast<X86Operand*>(Operands[2]);
1644 if (isSrcOp(*Op1) && Op2->isReg()) {
1646 unsigned reg = Op2->getReg();
1647 bool isLods = Name == "lods";
1648 if (reg == X86::AL && (isLods || Name == "lodsb"))
1650 else if (reg == X86::AX && (isLods || Name == "lodsw"))
1652 else if (reg == X86::EAX && (isLods || Name == "lodsl"))
1654 else if (reg == X86::RAX && (isLods || Name == "lodsq"))
1659 Operands.pop_back();
1660 Operands.pop_back();
1664 static_cast<X86Operand*>(Operands[0])->setTokenValue(ins);
1668 // Transform "stos[bwl] {%al,%ax,%eax,%rax},%es:(%edi)" into "stos[bwl]"
1669 if (Name.startswith("stos") && Operands.size() == 3 &&
1670 (Name == "stos" || Name == "stosb" || Name == "stosw" ||
1671 Name == "stosl" || (is64BitMode() && Name == "stosq"))) {
1672 X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
1673 X86Operand *Op2 = static_cast<X86Operand*>(Operands[2]);
1674 if (isDstOp(*Op2) && Op1->isReg()) {
1676 unsigned reg = Op1->getReg();
1677 bool isStos = Name == "stos";
1678 if (reg == X86::AL && (isStos || Name == "stosb"))
1680 else if (reg == X86::AX && (isStos || Name == "stosw"))
1682 else if (reg == X86::EAX && (isStos || Name == "stosl"))
1684 else if (reg == X86::RAX && (isStos || Name == "stosq"))
1689 Operands.pop_back();
1690 Operands.pop_back();
1694 static_cast<X86Operand*>(Operands[0])->setTokenValue(ins);
1699 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
1701 if ((Name.startswith("shr") || Name.startswith("sar") ||
1702 Name.startswith("shl") || Name.startswith("sal") ||
1703 Name.startswith("rcl") || Name.startswith("rcr") ||
1704 Name.startswith("rol") || Name.startswith("ror")) &&
1705 Operands.size() == 3) {
1706 if (isParsingIntelSyntax()) {
1708 X86Operand *Op1 = static_cast<X86Operand*>(Operands[2]);
1709 if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
1710 cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) {
1712 Operands.pop_back();
1715 X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
1716 if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
1717 cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) {
1719 Operands.erase(Operands.begin() + 1);
1724 // Transforms "int $3" into "int3" as a size optimization. We can't write an
1725 // instalias with an immediate operand yet.
1726 if (Name == "int" && Operands.size() == 2) {
1727 X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
1728 if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
1729 cast<MCConstantExpr>(Op1->getImm())->getValue() == 3) {
1731 Operands.erase(Operands.begin() + 1);
1732 static_cast<X86Operand*>(Operands[0])->setTokenValue("int3");
1739 static bool convertToSExti8(MCInst &Inst, unsigned Opcode, unsigned Reg,
1742 TmpInst.setOpcode(Opcode);
1744 TmpInst.addOperand(MCOperand::CreateReg(Reg));
1745 TmpInst.addOperand(MCOperand::CreateReg(Reg));
1746 TmpInst.addOperand(Inst.getOperand(0));
1751 static bool convert16i16to16ri8(MCInst &Inst, unsigned Opcode,
1752 bool isCmp = false) {
1753 if (!Inst.getOperand(0).isImm() ||
1754 !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
1757 return convertToSExti8(Inst, Opcode, X86::AX, isCmp);
1760 static bool convert32i32to32ri8(MCInst &Inst, unsigned Opcode,
1761 bool isCmp = false) {
1762 if (!Inst.getOperand(0).isImm() ||
1763 !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
1766 return convertToSExti8(Inst, Opcode, X86::EAX, isCmp);
1769 static bool convert64i32to64ri8(MCInst &Inst, unsigned Opcode,
1770 bool isCmp = false) {
1771 if (!Inst.getOperand(0).isImm() ||
1772 !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
1775 return convertToSExti8(Inst, Opcode, X86::RAX, isCmp);
1779 processInstruction(MCInst &Inst,
1780 const SmallVectorImpl<MCParsedAsmOperand*> &Ops) {
1781 switch (Inst.getOpcode()) {
1782 default: return false;
1783 case X86::AND16i16: return convert16i16to16ri8(Inst, X86::AND16ri8);
1784 case X86::AND32i32: return convert32i32to32ri8(Inst, X86::AND32ri8);
1785 case X86::AND64i32: return convert64i32to64ri8(Inst, X86::AND64ri8);
1786 case X86::XOR16i16: return convert16i16to16ri8(Inst, X86::XOR16ri8);
1787 case X86::XOR32i32: return convert32i32to32ri8(Inst, X86::XOR32ri8);
1788 case X86::XOR64i32: return convert64i32to64ri8(Inst, X86::XOR64ri8);
1789 case X86::OR16i16: return convert16i16to16ri8(Inst, X86::OR16ri8);
1790 case X86::OR32i32: return convert32i32to32ri8(Inst, X86::OR32ri8);
1791 case X86::OR64i32: return convert64i32to64ri8(Inst, X86::OR64ri8);
1792 case X86::CMP16i16: return convert16i16to16ri8(Inst, X86::CMP16ri8, true);
1793 case X86::CMP32i32: return convert32i32to32ri8(Inst, X86::CMP32ri8, true);
1794 case X86::CMP64i32: return convert64i32to64ri8(Inst, X86::CMP64ri8, true);
1795 case X86::ADD16i16: return convert16i16to16ri8(Inst, X86::ADD16ri8);
1796 case X86::ADD32i32: return convert32i32to32ri8(Inst, X86::ADD32ri8);
1797 case X86::ADD64i32: return convert64i32to64ri8(Inst, X86::ADD64ri8);
1798 case X86::SUB16i16: return convert16i16to16ri8(Inst, X86::SUB16ri8);
1799 case X86::SUB32i32: return convert32i32to32ri8(Inst, X86::SUB32ri8);
1800 case X86::SUB64i32: return convert64i32to64ri8(Inst, X86::SUB64ri8);
1801 case X86::ADC16i16: return convert16i16to16ri8(Inst, X86::ADC16ri8);
1802 case X86::ADC32i32: return convert32i32to32ri8(Inst, X86::ADC32ri8);
1803 case X86::ADC64i32: return convert64i32to64ri8(Inst, X86::ADC64ri8);
1804 case X86::SBB16i16: return convert16i16to16ri8(Inst, X86::SBB16ri8);
1805 case X86::SBB32i32: return convert32i32to32ri8(Inst, X86::SBB32ri8);
1806 case X86::SBB64i32: return convert64i32to64ri8(Inst, X86::SBB64ri8);
1810 static const char *getSubtargetFeatureName(unsigned Val);
1812 MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1813 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1814 MCStreamer &Out, unsigned &ErrorInfo,
1815 bool MatchingInlineAsm) {
1816 assert(!Operands.empty() && "Unexpect empty operand list!");
1817 X86Operand *Op = static_cast<X86Operand*>(Operands[0]);
1818 assert(Op->isToken() && "Leading operand should always be a mnemonic!");
1819 ArrayRef<SMRange> EmptyRanges = ArrayRef<SMRange>();
1821 // First, handle aliases that expand to multiple instructions.
1822 // FIXME: This should be replaced with a real .td file alias mechanism.
1823 // Also, MatchInstructionImpl should actually *do* the EmitInstruction
1825 if (Op->getToken() == "fstsw" || Op->getToken() == "fstcw" ||
1826 Op->getToken() == "fstsww" || Op->getToken() == "fstcww" ||
1827 Op->getToken() == "finit" || Op->getToken() == "fsave" ||
1828 Op->getToken() == "fstenv" || Op->getToken() == "fclex") {
1830 Inst.setOpcode(X86::WAIT);
1832 if (!MatchingInlineAsm)
1833 Out.EmitInstruction(Inst);
1836 StringSwitch<const char*>(Op->getToken())
1837 .Case("finit", "fninit")
1838 .Case("fsave", "fnsave")
1839 .Case("fstcw", "fnstcw")
1840 .Case("fstcww", "fnstcw")
1841 .Case("fstenv", "fnstenv")
1842 .Case("fstsw", "fnstsw")
1843 .Case("fstsww", "fnstsw")
1844 .Case("fclex", "fnclex")
1846 assert(Repl && "Unknown wait-prefixed instruction");
1848 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
1851 bool WasOriginallyInvalidOperand = false;
1854 // First, try a direct match.
1855 switch (MatchInstructionImpl(Operands, Inst,
1856 ErrorInfo, MatchingInlineAsm,
1857 isParsingIntelSyntax())) {
1860 // Some instructions need post-processing to, for example, tweak which
1861 // encoding is selected. Loop on it while changes happen so the
1862 // individual transformations can chain off each other.
1863 if (!MatchingInlineAsm)
1864 while (processInstruction(Inst, Operands))
1868 if (!MatchingInlineAsm)
1869 Out.EmitInstruction(Inst);
1870 Opcode = Inst.getOpcode();
1872 case Match_MissingFeature: {
1873 assert(ErrorInfo && "Unknown missing feature!");
1874 // Special case the error message for the very common case where only
1875 // a single subtarget feature is missing.
1876 std::string Msg = "instruction requires:";
1878 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
1879 if (ErrorInfo & Mask) {
1881 Msg += getSubtargetFeatureName(ErrorInfo & Mask);
1885 return Error(IDLoc, Msg, EmptyRanges, MatchingInlineAsm);
1887 case Match_InvalidOperand:
1888 WasOriginallyInvalidOperand = true;
1890 case Match_MnemonicFail:
1894 // FIXME: Ideally, we would only attempt suffix matches for things which are
1895 // valid prefixes, and we could just infer the right unambiguous
1896 // type. However, that requires substantially more matcher support than the
1899 // Change the operand to point to a temporary token.
1900 StringRef Base = Op->getToken();
1901 SmallString<16> Tmp;
1904 Op->setTokenValue(Tmp.str());
1906 // If this instruction starts with an 'f', then it is a floating point stack
1907 // instruction. These come in up to three forms for 32-bit, 64-bit, and
1908 // 80-bit floating point, which use the suffixes s,l,t respectively.
1910 // Otherwise, we assume that this may be an integer instruction, which comes
1911 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
1912 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
1914 // Check for the various suffix matches.
1915 Tmp[Base.size()] = Suffixes[0];
1916 unsigned ErrorInfoIgnore;
1917 unsigned ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
1918 unsigned Match1, Match2, Match3, Match4;
1920 Match1 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
1921 isParsingIntelSyntax());
1922 // If this returned as a missing feature failure, remember that.
1923 if (Match1 == Match_MissingFeature)
1924 ErrorInfoMissingFeature = ErrorInfoIgnore;
1925 Tmp[Base.size()] = Suffixes[1];
1926 Match2 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
1927 isParsingIntelSyntax());
1928 // If this returned as a missing feature failure, remember that.
1929 if (Match2 == Match_MissingFeature)
1930 ErrorInfoMissingFeature = ErrorInfoIgnore;
1931 Tmp[Base.size()] = Suffixes[2];
1932 Match3 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
1933 isParsingIntelSyntax());
1934 // If this returned as a missing feature failure, remember that.
1935 if (Match3 == Match_MissingFeature)
1936 ErrorInfoMissingFeature = ErrorInfoIgnore;
1937 Tmp[Base.size()] = Suffixes[3];
1938 Match4 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
1939 isParsingIntelSyntax());
1940 // If this returned as a missing feature failure, remember that.
1941 if (Match4 == Match_MissingFeature)
1942 ErrorInfoMissingFeature = ErrorInfoIgnore;
1944 // Restore the old token.
1945 Op->setTokenValue(Base);
1947 // If exactly one matched, then we treat that as a successful match (and the
1948 // instruction will already have been filled in correctly, since the failing
1949 // matches won't have modified it).
1950 unsigned NumSuccessfulMatches =
1951 (Match1 == Match_Success) + (Match2 == Match_Success) +
1952 (Match3 == Match_Success) + (Match4 == Match_Success);
1953 if (NumSuccessfulMatches == 1) {
1955 if (!MatchingInlineAsm)
1956 Out.EmitInstruction(Inst);
1957 Opcode = Inst.getOpcode();
1961 // Otherwise, the match failed, try to produce a decent error message.
1963 // If we had multiple suffix matches, then identify this as an ambiguous
1965 if (NumSuccessfulMatches > 1) {
1967 unsigned NumMatches = 0;
1968 if (Match1 == Match_Success) MatchChars[NumMatches++] = Suffixes[0];
1969 if (Match2 == Match_Success) MatchChars[NumMatches++] = Suffixes[1];
1970 if (Match3 == Match_Success) MatchChars[NumMatches++] = Suffixes[2];
1971 if (Match4 == Match_Success) MatchChars[NumMatches++] = Suffixes[3];
1973 SmallString<126> Msg;
1974 raw_svector_ostream OS(Msg);
1975 OS << "ambiguous instructions require an explicit suffix (could be ";
1976 for (unsigned i = 0; i != NumMatches; ++i) {
1979 if (i + 1 == NumMatches)
1981 OS << "'" << Base << MatchChars[i] << "'";
1984 Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
1988 // Okay, we know that none of the variants matched successfully.
1990 // If all of the instructions reported an invalid mnemonic, then the original
1991 // mnemonic was invalid.
1992 if ((Match1 == Match_MnemonicFail) && (Match2 == Match_MnemonicFail) &&
1993 (Match3 == Match_MnemonicFail) && (Match4 == Match_MnemonicFail)) {
1994 if (!WasOriginallyInvalidOperand) {
1995 ArrayRef<SMRange> Ranges = MatchingInlineAsm ? EmptyRanges :
1997 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
1998 Ranges, MatchingInlineAsm);
2001 // Recover location info for the operand if we know which was the problem.
2002 if (ErrorInfo != ~0U) {
2003 if (ErrorInfo >= Operands.size())
2004 return Error(IDLoc, "too few operands for instruction",
2005 EmptyRanges, MatchingInlineAsm);
2007 X86Operand *Operand = (X86Operand*)Operands[ErrorInfo];
2008 if (Operand->getStartLoc().isValid()) {
2009 SMRange OperandRange = Operand->getLocRange();
2010 return Error(Operand->getStartLoc(), "invalid operand for instruction",
2011 OperandRange, MatchingInlineAsm);
2015 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2019 // If one instruction matched with a missing feature, report this as a
2021 if ((Match1 == Match_MissingFeature) + (Match2 == Match_MissingFeature) +
2022 (Match3 == Match_MissingFeature) + (Match4 == Match_MissingFeature) == 1){
2023 std::string Msg = "instruction requires:";
2025 for (unsigned i = 0; i < (sizeof(ErrorInfoMissingFeature)*8-1); ++i) {
2026 if (ErrorInfoMissingFeature & Mask) {
2028 Msg += getSubtargetFeatureName(ErrorInfoMissingFeature & Mask);
2032 return Error(IDLoc, Msg, EmptyRanges, MatchingInlineAsm);
2035 // If one instruction matched with an invalid operand, report this as an
2037 if ((Match1 == Match_InvalidOperand) + (Match2 == Match_InvalidOperand) +
2038 (Match3 == Match_InvalidOperand) + (Match4 == Match_InvalidOperand) == 1){
2039 Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2044 // If all of these were an outright failure, report it in a useless way.
2045 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
2046 EmptyRanges, MatchingInlineAsm);
2051 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
2052 StringRef IDVal = DirectiveID.getIdentifier();
2053 if (IDVal == ".word")
2054 return ParseDirectiveWord(2, DirectiveID.getLoc());
2055 else if (IDVal.startswith(".code"))
2056 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
2057 else if (IDVal.startswith(".att_syntax")) {
2058 getParser().setAssemblerDialect(0);
2060 } else if (IDVal.startswith(".intel_syntax")) {
2061 getParser().setAssemblerDialect(1);
2062 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2063 if(Parser.getTok().getString() == "noprefix") {
2064 // FIXME : Handle noprefix
2074 /// ParseDirectiveWord
2075 /// ::= .word [ expression (, expression)* ]
2076 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2077 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2079 const MCExpr *Value;
2080 if (getParser().parseExpression(Value))
2083 getParser().getStreamer().EmitValue(Value, Size);
2085 if (getLexer().is(AsmToken::EndOfStatement))
2088 // FIXME: Improve diagnostic.
2089 if (getLexer().isNot(AsmToken::Comma))
2090 return Error(L, "unexpected token in directive");
2099 /// ParseDirectiveCode
2100 /// ::= .code32 | .code64
2101 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
2102 if (IDVal == ".code32") {
2104 if (is64BitMode()) {
2106 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2108 } else if (IDVal == ".code64") {
2110 if (!is64BitMode()) {
2112 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
2115 return Error(L, "unexpected directive " + IDVal);
2121 // Force static initialization.
2122 extern "C" void LLVMInitializeX86AsmParser() {
2123 RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target);
2124 RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target);
2127 #define GET_REGISTER_MATCHER
2128 #define GET_MATCHER_IMPLEMENTATION
2129 #define GET_SUBTARGET_FEATURE_NAME
2130 #include "X86GenAsmMatcher.inc"