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/MCContext.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCParser/MCAsmLexer.h"
20 #include "llvm/MC/MCParser/MCAsmParser.h"
21 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
22 #include "llvm/MC/MCRegisterInfo.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/MC/MCSubtargetInfo.h"
25 #include "llvm/MC/MCSymbol.h"
26 #include "llvm/MC/MCTargetAsmParser.h"
27 #include "llvm/Support/SourceMgr.h"
28 #include "llvm/Support/TargetRegistry.h"
29 #include "llvm/Support/raw_ostream.h"
36 class X86AsmParser : public MCTargetAsmParser {
39 ParseInstructionInfo *InstInfo;
41 MCAsmParser &getParser() const { return Parser; }
43 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
45 bool Error(SMLoc L, const Twine &Msg,
46 ArrayRef<SMRange> Ranges = ArrayRef<SMRange>(),
47 bool MatchingInlineAsm = false) {
48 if (MatchingInlineAsm) return true;
49 return Parser.Error(L, Msg, Ranges);
52 X86Operand *ErrorOperand(SMLoc Loc, StringRef Msg) {
57 X86Operand *ParseOperand();
58 X86Operand *ParseATTOperand();
59 X86Operand *ParseIntelOperand();
60 X86Operand *ParseIntelOffsetOfOperator(SMLoc StartLoc);
61 X86Operand *ParseIntelOperator(SMLoc StartLoc, unsigned OpKind);
62 X86Operand *ParseIntelMemOperand(unsigned SegReg, uint64_t ImmDisp,
64 X86Operand *ParseIntelBracExpression(unsigned SegReg, uint64_t ImmDisp,
66 X86Operand *ParseIntelVarWithQualifier(const MCExpr *&Disp,
68 X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
70 X86Operand *CreateMemForInlineAsm(const MCExpr *Disp, SMLoc Start, SMLoc End,
71 SMLoc SizeDirLoc, unsigned Size);
73 bool ParseIntelDotOperator(const MCExpr *Disp, const MCExpr **NewDisp,
74 SmallString<64> &Err);
76 bool ParseDirectiveWord(unsigned Size, SMLoc L);
77 bool ParseDirectiveCode(StringRef IDVal, SMLoc L);
79 bool processInstruction(MCInst &Inst,
80 const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
82 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
83 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
84 MCStreamer &Out, unsigned &ErrorInfo,
85 bool MatchingInlineAsm);
87 /// isSrcOp - Returns true if operand is either (%rsi) or %ds:%(rsi)
88 /// in 64bit mode or (%esi) or %es:(%esi) in 32bit mode.
89 bool isSrcOp(X86Operand &Op);
91 /// isDstOp - Returns true if operand is either (%rdi) or %es:(%rdi)
92 /// in 64bit mode or (%edi) or %es:(%edi) in 32bit mode.
93 bool isDstOp(X86Operand &Op);
95 bool is64BitMode() const {
96 // FIXME: Can tablegen auto-generate this?
97 return (STI.getFeatureBits() & X86::Mode64Bit) != 0;
100 unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(X86::Mode64Bit));
101 setAvailableFeatures(FB);
104 /// @name Auto-generated Matcher Functions
107 #define GET_ASSEMBLER_HEADER
108 #include "X86GenAsmMatcher.inc"
113 X86AsmParser(MCSubtargetInfo &sti, MCAsmParser &parser)
114 : MCTargetAsmParser(), STI(sti), Parser(parser), InstInfo(0) {
116 // Initialize the set of available features.
117 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
119 virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
121 virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
123 SmallVectorImpl<MCParsedAsmOperand*> &Operands);
125 virtual bool ParseDirective(AsmToken DirectiveID);
127 bool isParsingIntelSyntax() {
128 return getParser().getAssemblerDialect();
131 } // end anonymous namespace
133 /// @name Auto-generated Match Functions
136 static unsigned MatchRegisterName(StringRef Name);
140 static bool isImmSExti16i8Value(uint64_t Value) {
141 return (( Value <= 0x000000000000007FULL)||
142 (0x000000000000FF80ULL <= Value && Value <= 0x000000000000FFFFULL)||
143 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
146 static bool isImmSExti32i8Value(uint64_t Value) {
147 return (( Value <= 0x000000000000007FULL)||
148 (0x00000000FFFFFF80ULL <= Value && Value <= 0x00000000FFFFFFFFULL)||
149 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
152 static bool isImmZExtu32u8Value(uint64_t Value) {
153 return (Value <= 0x00000000000000FFULL);
156 static bool isImmSExti64i8Value(uint64_t Value) {
157 return (( Value <= 0x000000000000007FULL)||
158 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
161 static bool isImmSExti64i32Value(uint64_t Value) {
162 return (( Value <= 0x000000007FFFFFFFULL)||
163 (0xFFFFFFFF80000000ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
167 /// X86Operand - Instances of this class represent a parsed X86 machine
169 struct X86Operand : public MCParsedAsmOperand {
177 SMLoc StartLoc, EndLoc;
210 X86Operand(KindTy K, SMLoc Start, SMLoc End)
211 : Kind(K), StartLoc(Start), EndLoc(End) {}
213 /// getStartLoc - Get the location of the first token of this operand.
214 SMLoc getStartLoc() const { return StartLoc; }
215 /// getEndLoc - Get the location of the last token of this operand.
216 SMLoc getEndLoc() const { return EndLoc; }
217 /// getLocRange - Get the range between the first and last token of this
219 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
220 /// getOffsetOfLoc - Get the location of the offset operator.
221 SMLoc getOffsetOfLoc() const { return OffsetOfLoc; }
223 virtual void print(raw_ostream &OS) const {}
225 StringRef getToken() const {
226 assert(Kind == Token && "Invalid access!");
227 return StringRef(Tok.Data, Tok.Length);
229 void setTokenValue(StringRef Value) {
230 assert(Kind == Token && "Invalid access!");
231 Tok.Data = Value.data();
232 Tok.Length = Value.size();
235 unsigned getReg() const {
236 assert(Kind == Register && "Invalid access!");
240 const MCExpr *getImm() const {
241 assert(Kind == Immediate && "Invalid access!");
245 const MCExpr *getMemDisp() const {
246 assert(Kind == Memory && "Invalid access!");
249 unsigned getMemSegReg() const {
250 assert(Kind == Memory && "Invalid access!");
253 unsigned getMemBaseReg() const {
254 assert(Kind == Memory && "Invalid access!");
257 unsigned getMemIndexReg() const {
258 assert(Kind == Memory && "Invalid access!");
261 unsigned getMemScale() const {
262 assert(Kind == Memory && "Invalid access!");
266 bool isToken() const {return Kind == Token; }
268 bool isImm() const { return Kind == Immediate; }
270 bool isImmSExti16i8() const {
274 // If this isn't a constant expr, just assume it fits and let relaxation
276 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
280 // Otherwise, check the value is in a range that makes sense for this
282 return isImmSExti16i8Value(CE->getValue());
284 bool isImmSExti32i8() const {
288 // If this isn't a constant expr, just assume it fits and let relaxation
290 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
294 // Otherwise, check the value is in a range that makes sense for this
296 return isImmSExti32i8Value(CE->getValue());
298 bool isImmZExtu32u8() const {
302 // If this isn't a constant expr, just assume it fits and let relaxation
304 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
308 // Otherwise, check the value is in a range that makes sense for this
310 return isImmZExtu32u8Value(CE->getValue());
312 bool isImmSExti64i8() const {
316 // If this isn't a constant expr, just assume it fits and let relaxation
318 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
322 // Otherwise, check the value is in a range that makes sense for this
324 return isImmSExti64i8Value(CE->getValue());
326 bool isImmSExti64i32() const {
330 // If this isn't a constant expr, just assume it fits and let relaxation
332 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
336 // Otherwise, check the value is in a range that makes sense for this
338 return isImmSExti64i32Value(CE->getValue());
341 bool isOffsetOf() const {
342 return OffsetOfLoc.getPointer();
345 bool needAddressOf() const {
349 bool isMem() const { return Kind == Memory; }
350 bool isMem8() const {
351 return Kind == Memory && (!Mem.Size || Mem.Size == 8);
353 bool isMem16() const {
354 return Kind == Memory && (!Mem.Size || Mem.Size == 16);
356 bool isMem32() const {
357 return Kind == Memory && (!Mem.Size || Mem.Size == 32);
359 bool isMem64() const {
360 return Kind == Memory && (!Mem.Size || Mem.Size == 64);
362 bool isMem80() const {
363 return Kind == Memory && (!Mem.Size || Mem.Size == 80);
365 bool isMem128() const {
366 return Kind == Memory && (!Mem.Size || Mem.Size == 128);
368 bool isMem256() const {
369 return Kind == Memory && (!Mem.Size || Mem.Size == 256);
372 bool isMemVX32() const {
373 return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
374 getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
376 bool isMemVY32() const {
377 return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
378 getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
380 bool isMemVX64() const {
381 return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
382 getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
384 bool isMemVY64() const {
385 return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
386 getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
389 bool isAbsMem() const {
390 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
391 !getMemIndexReg() && getMemScale() == 1;
394 bool isReg() const { return Kind == Register; }
396 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
397 // Add as immediates when possible.
398 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
399 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
401 Inst.addOperand(MCOperand::CreateExpr(Expr));
404 void addRegOperands(MCInst &Inst, unsigned N) const {
405 assert(N == 1 && "Invalid number of operands!");
406 Inst.addOperand(MCOperand::CreateReg(getReg()));
409 void addImmOperands(MCInst &Inst, unsigned N) const {
410 assert(N == 1 && "Invalid number of operands!");
411 addExpr(Inst, getImm());
414 void addMem8Operands(MCInst &Inst, unsigned N) const {
415 addMemOperands(Inst, N);
417 void addMem16Operands(MCInst &Inst, unsigned N) const {
418 addMemOperands(Inst, N);
420 void addMem32Operands(MCInst &Inst, unsigned N) const {
421 addMemOperands(Inst, N);
423 void addMem64Operands(MCInst &Inst, unsigned N) const {
424 addMemOperands(Inst, N);
426 void addMem80Operands(MCInst &Inst, unsigned N) const {
427 addMemOperands(Inst, N);
429 void addMem128Operands(MCInst &Inst, unsigned N) const {
430 addMemOperands(Inst, N);
432 void addMem256Operands(MCInst &Inst, unsigned N) const {
433 addMemOperands(Inst, N);
435 void addMemVX32Operands(MCInst &Inst, unsigned N) const {
436 addMemOperands(Inst, N);
438 void addMemVY32Operands(MCInst &Inst, unsigned N) const {
439 addMemOperands(Inst, N);
441 void addMemVX64Operands(MCInst &Inst, unsigned N) const {
442 addMemOperands(Inst, N);
444 void addMemVY64Operands(MCInst &Inst, unsigned N) const {
445 addMemOperands(Inst, N);
448 void addMemOperands(MCInst &Inst, unsigned N) const {
449 assert((N == 5) && "Invalid number of operands!");
450 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
451 Inst.addOperand(MCOperand::CreateImm(getMemScale()));
452 Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
453 addExpr(Inst, getMemDisp());
454 Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
457 void addAbsMemOperands(MCInst &Inst, unsigned N) const {
458 assert((N == 1) && "Invalid number of operands!");
459 // Add as immediates when possible.
460 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
461 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
463 Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
466 static X86Operand *CreateToken(StringRef Str, SMLoc Loc) {
467 SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
468 X86Operand *Res = new X86Operand(Token, Loc, EndLoc);
469 Res->Tok.Data = Str.data();
470 Res->Tok.Length = Str.size();
474 static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
475 bool AddressOf = false,
476 SMLoc OffsetOfLoc = SMLoc()) {
477 X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc);
478 Res->Reg.RegNo = RegNo;
479 Res->AddressOf = AddressOf;
480 Res->OffsetOfLoc = OffsetOfLoc;
484 static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc){
485 X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc);
490 /// Create an absolute memory operand.
491 static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
493 X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
495 Res->Mem.Disp = Disp;
496 Res->Mem.BaseReg = 0;
497 Res->Mem.IndexReg = 0;
499 Res->Mem.Size = Size;
500 Res->AddressOf = false;
504 /// Create a generalized memory operand.
505 static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp,
506 unsigned BaseReg, unsigned IndexReg,
507 unsigned Scale, SMLoc StartLoc, SMLoc EndLoc,
509 // We should never just have a displacement, that should be parsed as an
510 // absolute memory operand.
511 assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
513 // The scale should always be one of {1,2,4,8}.
514 assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
516 X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
517 Res->Mem.SegReg = SegReg;
518 Res->Mem.Disp = Disp;
519 Res->Mem.BaseReg = BaseReg;
520 Res->Mem.IndexReg = IndexReg;
521 Res->Mem.Scale = Scale;
522 Res->Mem.Size = Size;
523 Res->AddressOf = false;
528 } // end anonymous namespace.
530 bool X86AsmParser::isSrcOp(X86Operand &Op) {
531 unsigned basereg = is64BitMode() ? X86::RSI : X86::ESI;
533 return (Op.isMem() &&
534 (Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::DS) &&
535 isa<MCConstantExpr>(Op.Mem.Disp) &&
536 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
537 Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0);
540 bool X86AsmParser::isDstOp(X86Operand &Op) {
541 unsigned basereg = is64BitMode() ? X86::RDI : X86::EDI;
544 (Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::ES) &&
545 isa<MCConstantExpr>(Op.Mem.Disp) &&
546 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
547 Op.Mem.BaseReg == basereg && Op.Mem.IndexReg == 0;
550 bool X86AsmParser::ParseRegister(unsigned &RegNo,
551 SMLoc &StartLoc, SMLoc &EndLoc) {
553 const AsmToken &PercentTok = Parser.getTok();
554 StartLoc = PercentTok.getLoc();
556 // If we encounter a %, ignore it. This code handles registers with and
557 // without the prefix, unprefixed registers can occur in cfi directives.
558 if (!isParsingIntelSyntax() && PercentTok.is(AsmToken::Percent))
559 Parser.Lex(); // Eat percent token.
561 const AsmToken &Tok = Parser.getTok();
562 EndLoc = Tok.getEndLoc();
564 if (Tok.isNot(AsmToken::Identifier)) {
565 if (isParsingIntelSyntax()) return true;
566 return Error(StartLoc, "invalid register name",
567 SMRange(StartLoc, EndLoc));
570 RegNo = MatchRegisterName(Tok.getString());
572 // If the match failed, try the register name as lowercase.
574 RegNo = MatchRegisterName(Tok.getString().lower());
576 if (!is64BitMode()) {
577 // FIXME: This should be done using Requires<In32BitMode> and
578 // Requires<In64BitMode> so "eiz" usage in 64-bit instructions can be also
580 // FIXME: Check AH, CH, DH, BH cannot be used in an instruction requiring a
582 if (RegNo == X86::RIZ ||
583 X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo) ||
584 X86II::isX86_64NonExtLowByteReg(RegNo) ||
585 X86II::isX86_64ExtendedReg(RegNo))
586 return Error(StartLoc, "register %"
587 + Tok.getString() + " is only available in 64-bit mode",
588 SMRange(StartLoc, EndLoc));
591 // Parse "%st" as "%st(0)" and "%st(1)", which is multiple tokens.
592 if (RegNo == 0 && (Tok.getString() == "st" || Tok.getString() == "ST")) {
594 Parser.Lex(); // Eat 'st'
596 // Check to see if we have '(4)' after %st.
597 if (getLexer().isNot(AsmToken::LParen))
602 const AsmToken &IntTok = Parser.getTok();
603 if (IntTok.isNot(AsmToken::Integer))
604 return Error(IntTok.getLoc(), "expected stack index");
605 switch (IntTok.getIntVal()) {
606 case 0: RegNo = X86::ST0; break;
607 case 1: RegNo = X86::ST1; break;
608 case 2: RegNo = X86::ST2; break;
609 case 3: RegNo = X86::ST3; break;
610 case 4: RegNo = X86::ST4; break;
611 case 5: RegNo = X86::ST5; break;
612 case 6: RegNo = X86::ST6; break;
613 case 7: RegNo = X86::ST7; break;
614 default: return Error(IntTok.getLoc(), "invalid stack index");
617 if (getParser().Lex().isNot(AsmToken::RParen))
618 return Error(Parser.getTok().getLoc(), "expected ')'");
620 EndLoc = Parser.getTok().getEndLoc();
621 Parser.Lex(); // Eat ')'
625 EndLoc = Parser.getTok().getEndLoc();
627 // If this is "db[0-7]", match it as an alias
629 if (RegNo == 0 && Tok.getString().size() == 3 &&
630 Tok.getString().startswith("db")) {
631 switch (Tok.getString()[2]) {
632 case '0': RegNo = X86::DR0; break;
633 case '1': RegNo = X86::DR1; break;
634 case '2': RegNo = X86::DR2; break;
635 case '3': RegNo = X86::DR3; break;
636 case '4': RegNo = X86::DR4; break;
637 case '5': RegNo = X86::DR5; break;
638 case '6': RegNo = X86::DR6; break;
639 case '7': RegNo = X86::DR7; break;
643 EndLoc = Parser.getTok().getEndLoc();
644 Parser.Lex(); // Eat it.
650 if (isParsingIntelSyntax()) return true;
651 return Error(StartLoc, "invalid register name",
652 SMRange(StartLoc, EndLoc));
655 Parser.Lex(); // Eat identifier token.
659 X86Operand *X86AsmParser::ParseOperand() {
660 if (isParsingIntelSyntax())
661 return ParseIntelOperand();
662 return ParseATTOperand();
665 /// getIntelMemOperandSize - Return intel memory operand size.
666 static unsigned getIntelMemOperandSize(StringRef OpStr) {
667 unsigned Size = StringSwitch<unsigned>(OpStr)
668 .Cases("BYTE", "byte", 8)
669 .Cases("WORD", "word", 16)
670 .Cases("DWORD", "dword", 32)
671 .Cases("QWORD", "qword", 64)
672 .Cases("XWORD", "xword", 80)
673 .Cases("XMMWORD", "xmmword", 128)
674 .Cases("YMMWORD", "ymmword", 256)
679 enum IntelBracExprState {
685 IBES_REGISTER_STAR_INTEGER,
695 class IntelBracExprStateMachine {
696 IntelBracExprState State;
697 unsigned BaseReg, IndexReg, Scale;
706 IntelBracExprStateMachine(MCAsmParser &parser, int64_t disp) :
707 State(IBES_START), BaseReg(0), IndexReg(0), Scale(1), Disp(disp),
708 TmpReg(0), TmpInteger(0), isPlus(true) {}
710 unsigned getBaseReg() { return BaseReg; }
711 unsigned getIndexReg() { return IndexReg; }
712 unsigned getScale() { return Scale; }
713 int64_t getDisp() { return Disp; }
714 bool isValidEndState() { return State == IBES_RBRAC; }
730 // If we already have a BaseReg, then assume this is the IndexReg with a
735 assert (!IndexReg && "BaseReg/IndexReg already set!");
740 case IBES_INDEX_REGISTER:
763 // If we already have a BaseReg, then assume this is the IndexReg with a
768 assert (!IndexReg && "BaseReg/IndexReg already set!");
773 case IBES_INDEX_REGISTER:
779 void onRegister(unsigned Reg) {
785 State = IBES_REGISTER;
788 case IBES_INTEGER_STAR:
789 assert (!IndexReg && "IndexReg already set!");
790 State = IBES_INDEX_REGISTER;
802 State = IBES_DISP_EXPR;
806 void onInteger(int64_t TmpInt) {
812 State = IBES_INTEGER;
816 State = IBES_INTEGER;
819 case IBES_REGISTER_STAR:
820 assert (!IndexReg && "IndexReg already set!");
821 State = IBES_INDEX_REGISTER;
833 State = IBES_INTEGER_STAR;
836 State = IBES_REGISTER_STAR;
868 // If we already have a BaseReg, then assume this is the IndexReg with a
873 assert (!IndexReg && "BaseReg/IndexReg already set!");
878 case IBES_INDEX_REGISTER:
885 X86Operand *X86AsmParser::CreateMemForInlineAsm(const MCExpr *Disp, SMLoc Start,
886 SMLoc End, SMLoc SizeDirLoc,
888 bool NeedSizeDir = false;
889 bool IsVarDecl = false;
890 if (const MCSymbolRefExpr *SymRef = dyn_cast<MCSymbolRefExpr>(Disp)) {
891 const MCSymbol &Sym = SymRef->getSymbol();
892 // FIXME: The SemaLookup will fail if the name is anything other then an
894 // FIXME: Pass a valid SMLoc.
895 unsigned tLength, tSize, tType;
896 SemaCallback->LookupInlineAsmIdentifier(Sym.getName(), NULL, tLength,
897 tSize, tType, IsVarDecl);
899 Size = tType * 8; // Size is in terms of bits in this context.
900 NeedSizeDir = Size > 0;
904 // If this is not a VarDecl then assume it is a FuncDecl or some other label
905 // reference. We need an 'r' constraint here, so we need to create register
906 // operand to ensure proper matching. Just pick a GPR based on the size of
909 unsigned RegNo = is64BitMode() ? X86::RBX : X86::EBX;
910 return X86Operand::CreateReg(RegNo, Start, End, /*AddressOf=*/true);
914 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_SizeDirective, SizeDirLoc,
917 // When parsing inline assembly we set the base register to a non-zero value
918 // as we don't know the actual value at this time. This is necessary to
919 // get the matching correct in some cases.
920 return X86Operand::CreateMem(/*SegReg*/0, Disp, /*BaseReg*/1, /*IndexReg*/0,
921 /*Scale*/1, Start, End, Size);
924 X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
927 const AsmToken &Tok = Parser.getTok();
928 SMLoc Start = Tok.getLoc(), End = Tok.getEndLoc();
931 if (getLexer().isNot(AsmToken::LBrac))
932 return ErrorOperand(Start, "Expected '[' token!");
937 // Try to handle '[' 'Symbol' ']'
938 if (getLexer().is(AsmToken::Identifier)) {
939 if (ParseRegister(TmpReg, Start, End)) {
941 SMLoc IdentStart = Tok.getLoc();
942 if (getParser().parseExpression(Disp, End))
945 if (X86Operand *Err = ParseIntelVarWithQualifier(Disp, IdentStart))
948 if (getLexer().isNot(AsmToken::RBrac))
949 return ErrorOperand(Parser.getTok().getLoc(), "Expected ']' token!");
951 // FIXME: We don't handle 'ImmDisp' '[' 'Symbol' ']'.
953 return ErrorOperand(Start, "Unsupported immediate displacement!");
955 // Adjust the EndLoc due to the ']'.
956 End = SMLoc::getFromPointer(Parser.getTok().getEndLoc().getPointer()-1);
958 if (!isParsingInlineAsm())
959 return X86Operand::CreateMem(Disp, Start, End, Size);
961 // We want the size directive before the '['.
962 SMLoc SizeDirLoc = SMLoc::getFromPointer(Start.getPointer()-1);
963 return CreateMemForInlineAsm(Disp, Start, End, SizeDirLoc, Size);
967 // Parse [ BaseReg + Scale*IndexReg + Disp ]. We may have already parsed an
968 // immediate displacement before the bracketed expression.
970 IntelBracExprStateMachine SM(Parser, ImmDisp);
972 // If we parsed a register, then the end loc has already been set and
973 // the identifier has already been lexed. We also need to update the
976 SM.onRegister(TmpReg);
978 const MCExpr *Disp = 0;
980 bool UpdateLocLex = true;
982 // The period in the dot operator (e.g., [ebx].foo.bar) is parsed as an
983 // identifier. Don't try an parse it as a register.
984 if (Tok.getString().startswith("."))
987 switch (getLexer().getKind()) {
989 if (SM.isValidEndState()) {
993 return ErrorOperand(Tok.getLoc(), "Unexpected token!");
995 case AsmToken::Identifier: {
996 // This could be a register or a displacement expression.
997 if(!ParseRegister(TmpReg, Start, End)) {
998 SM.onRegister(TmpReg);
999 UpdateLocLex = false;
1001 } else if (!getParser().parseExpression(Disp, End)) {
1003 UpdateLocLex = false;
1006 return ErrorOperand(Tok.getLoc(), "Unexpected identifier!");
1008 case AsmToken::Integer: {
1009 int64_t Val = Tok.getIntVal();
1013 case AsmToken::Plus: SM.onPlus(); break;
1014 case AsmToken::Minus: SM.onMinus(); break;
1015 case AsmToken::Star: SM.onStar(); break;
1016 case AsmToken::LBrac: SM.onLBrac(); break;
1017 case AsmToken::RBrac: SM.onRBrac(); break;
1019 if (!Done && UpdateLocLex) {
1021 Parser.Lex(); // Consume the token.
1026 Disp = MCConstantExpr::Create(SM.getDisp(), getContext());
1028 // Parse the dot operator (e.g., [ebx].foo.bar).
1029 if (Tok.getString().startswith(".")) {
1030 SmallString<64> Err;
1031 const MCExpr *NewDisp;
1032 if (ParseIntelDotOperator(Disp, &NewDisp, Err))
1033 return ErrorOperand(Tok.getLoc(), Err);
1035 End = Parser.getTok().getEndLoc();
1036 Parser.Lex(); // Eat the field.
1040 int BaseReg = SM.getBaseReg();
1041 int IndexReg = SM.getIndexReg();
1044 if (!BaseReg && !IndexReg) {
1046 return X86Operand::CreateMem(Disp, Start, End);
1048 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, Start, End, Size);
1051 int Scale = SM.getScale();
1052 return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
1056 // Inline assembly may use variable names with namespace alias qualifiers.
1057 X86Operand *X86AsmParser::ParseIntelVarWithQualifier(const MCExpr *&Disp,
1058 SMLoc &IdentStart) {
1059 // We should only see Foo::Bar if we're parsing inline assembly.
1060 if (!isParsingInlineAsm())
1063 // If we don't see a ':' then there can't be a qualifier.
1064 if (getLexer().isNot(AsmToken::Colon))
1069 const AsmToken &Tok = Parser.getTok();
1070 SMLoc IdentEnd = Tok.getEndLoc();
1072 switch (getLexer().getKind()) {
1076 case AsmToken::Colon:
1077 getLexer().Lex(); // Consume ':'.
1078 if (getLexer().isNot(AsmToken::Colon))
1079 return ErrorOperand(Tok.getLoc(), "Expected ':' token!");
1080 getLexer().Lex(); // Consume second ':'.
1081 if (getLexer().isNot(AsmToken::Identifier))
1082 return ErrorOperand(Tok.getLoc(), "Expected an identifier token!");
1084 case AsmToken::Identifier:
1085 IdentEnd = Tok.getEndLoc();
1086 getLexer().Lex(); // Consume the identifier.
1090 size_t Len = IdentEnd.getPointer() - IdentStart.getPointer();
1091 StringRef Identifier(IdentStart.getPointer(), Len);
1092 MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
1093 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1094 Disp = MCSymbolRefExpr::Create(Sym, Variant, getParser().getContext());
1098 /// ParseIntelMemOperand - Parse intel style memory operand.
1099 X86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg,
1102 const AsmToken &Tok = Parser.getTok();
1105 unsigned Size = getIntelMemOperandSize(Tok.getString());
1108 assert ((Tok.getString() == "PTR" || Tok.getString() == "ptr") &&
1109 "Unexpected token!");
1113 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1114 if (getLexer().is(AsmToken::Integer)) {
1115 const AsmToken &IntTok = Parser.getTok();
1116 if (isParsingInlineAsm())
1117 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix,
1119 uint64_t ImmDisp = IntTok.getIntVal();
1120 Parser.Lex(); // Eat the integer.
1121 if (getLexer().isNot(AsmToken::LBrac))
1122 return ErrorOperand(Start, "Expected '[' token!");
1123 return ParseIntelBracExpression(SegReg, ImmDisp, Size);
1126 if (getLexer().is(AsmToken::LBrac))
1127 return ParseIntelBracExpression(SegReg, ImmDisp, Size);
1129 if (!ParseRegister(SegReg, Start, End)) {
1130 // Handel SegReg : [ ... ]
1131 if (getLexer().isNot(AsmToken::Colon))
1132 return ErrorOperand(Start, "Expected ':' token!");
1133 Parser.Lex(); // Eat :
1134 if (getLexer().isNot(AsmToken::LBrac))
1135 return ErrorOperand(Start, "Expected '[' token!");
1136 return ParseIntelBracExpression(SegReg, ImmDisp, Size);
1139 const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
1140 SMLoc IdentStart = Tok.getLoc();
1141 if (getParser().parseExpression(Disp, End))
1144 if (!isParsingInlineAsm())
1145 return X86Operand::CreateMem(Disp, Start, End, Size);
1147 if (X86Operand *Err = ParseIntelVarWithQualifier(Disp, IdentStart))
1150 return CreateMemForInlineAsm(Disp, Start, End, Start, Size);
1153 /// Parse the '.' operator.
1154 bool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp,
1155 const MCExpr **NewDisp,
1156 SmallString<64> &Err) {
1157 AsmToken Tok = *&Parser.getTok();
1158 uint64_t OrigDispVal, DotDispVal;
1160 // FIXME: Handle non-constant expressions.
1161 if (const MCConstantExpr *OrigDisp = dyn_cast<MCConstantExpr>(Disp)) {
1162 OrigDispVal = OrigDisp->getValue();
1164 Err = "Non-constant offsets are not supported!";
1169 StringRef DotDispStr = Tok.getString().drop_front(1);
1171 // .Imm gets lexed as a real.
1172 if (Tok.is(AsmToken::Real)) {
1174 DotDispStr.getAsInteger(10, DotDisp);
1175 DotDispVal = DotDisp.getZExtValue();
1176 } else if (Tok.is(AsmToken::Identifier)) {
1177 // We should only see an identifier when parsing the original inline asm.
1178 // The front-end should rewrite this in terms of immediates.
1179 assert (isParsingInlineAsm() && "Unexpected field name!");
1182 std::pair<StringRef, StringRef> BaseMember = DotDispStr.split('.');
1183 if (SemaCallback->LookupInlineAsmField(BaseMember.first, BaseMember.second,
1185 Err = "Unable to lookup field reference!";
1188 DotDispVal = DotDisp;
1190 Err = "Unexpected token type!";
1194 if (isParsingInlineAsm() && Tok.is(AsmToken::Identifier)) {
1195 SMLoc Loc = SMLoc::getFromPointer(DotDispStr.data());
1196 unsigned Len = DotDispStr.size();
1197 unsigned Val = OrigDispVal + DotDispVal;
1198 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_DotOperator, Loc, Len,
1202 *NewDisp = MCConstantExpr::Create(OrigDispVal + DotDispVal, getContext());
1206 /// Parse the 'offset' operator. This operator is used to specify the
1207 /// location rather then the content of a variable.
1208 X86Operand *X86AsmParser::ParseIntelOffsetOfOperator(SMLoc Start) {
1209 SMLoc OffsetOfLoc = Start;
1210 Parser.Lex(); // Eat offset.
1211 Start = Parser.getTok().getLoc();
1212 assert (Parser.getTok().is(AsmToken::Identifier) && "Expected an identifier");
1216 if (getParser().parseExpression(Val, End))
1217 return ErrorOperand(Start, "Unable to parse expression!");
1219 // Don't emit the offset operator.
1220 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Skip, OffsetOfLoc, 7));
1222 // The offset operator will have an 'r' constraint, thus we need to create
1223 // register operand to ensure proper matching. Just pick a GPR based on
1224 // the size of a pointer.
1225 unsigned RegNo = is64BitMode() ? X86::RBX : X86::EBX;
1226 return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
1230 enum IntelOperatorKind {
1236 /// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator
1237 /// returns the number of elements in an array. It returns the value 1 for
1238 /// non-array variables. The SIZE operator returns the size of a C or C++
1239 /// variable. A variable's size is the product of its LENGTH and TYPE. The
1240 /// TYPE operator returns the size of a C or C++ type or variable. If the
1241 /// variable is an array, TYPE returns the size of a single element.
1242 X86Operand *X86AsmParser::ParseIntelOperator(SMLoc Start, unsigned OpKind) {
1243 SMLoc TypeLoc = Start;
1244 Parser.Lex(); // Eat offset.
1245 Start = Parser.getTok().getLoc();
1246 assert (Parser.getTok().is(AsmToken::Identifier) && "Expected an identifier");
1250 if (getParser().parseExpression(Val, End))
1253 unsigned Length = 0, Size = 0, Type = 0;
1254 if (const MCSymbolRefExpr *SymRef = dyn_cast<MCSymbolRefExpr>(Val)) {
1255 const MCSymbol &Sym = SymRef->getSymbol();
1256 // FIXME: The SemaLookup will fail if the name is anything other then an
1258 // FIXME: Pass a valid SMLoc.
1260 if (!SemaCallback->LookupInlineAsmIdentifier(Sym.getName(), NULL, Length,
1261 Size, Type, IsVarDecl))
1262 return ErrorOperand(Start, "Unable to lookup expr!");
1266 default: llvm_unreachable("Unexpected operand kind!");
1267 case IOK_LENGTH: CVal = Length; break;
1268 case IOK_SIZE: CVal = Size; break;
1269 case IOK_TYPE: CVal = Type; break;
1272 // Rewrite the type operator and the C or C++ type or variable in terms of an
1273 // immediate. E.g. TYPE foo -> $$4
1274 unsigned Len = End.getPointer() - TypeLoc.getPointer();
1275 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_Imm, TypeLoc, Len, CVal));
1277 const MCExpr *Imm = MCConstantExpr::Create(CVal, getContext());
1278 return X86Operand::CreateImm(Imm, Start, End);
1281 X86Operand *X86AsmParser::ParseIntelOperand() {
1282 SMLoc Start = Parser.getTok().getLoc(), End;
1283 StringRef AsmTokStr = Parser.getTok().getString();
1285 // Offset, length, type and size operators.
1286 if (isParsingInlineAsm()) {
1287 if (AsmTokStr == "offset" || AsmTokStr == "OFFSET")
1288 return ParseIntelOffsetOfOperator(Start);
1289 if (AsmTokStr == "length" || AsmTokStr == "LENGTH")
1290 return ParseIntelOperator(Start, IOK_LENGTH);
1291 if (AsmTokStr == "size" || AsmTokStr == "SIZE")
1292 return ParseIntelOperator(Start, IOK_SIZE);
1293 if (AsmTokStr == "type" || AsmTokStr == "TYPE")
1294 return ParseIntelOperator(Start, IOK_TYPE);
1298 if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Real) ||
1299 getLexer().is(AsmToken::Minus)) {
1301 bool isInteger = getLexer().is(AsmToken::Integer);
1302 if (!getParser().parseExpression(Val, End)) {
1303 if (isParsingInlineAsm())
1304 InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix, Start));
1306 if (getLexer().isNot(AsmToken::LBrac))
1307 return X86Operand::CreateImm(Val, Start, End);
1309 // Only positive immediates are valid.
1311 Error(Parser.getTok().getLoc(), "expected a positive immediate "
1312 "displacement before bracketed expr.");
1316 // Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
1317 if (uint64_t ImmDisp = dyn_cast<MCConstantExpr>(Val)->getValue())
1318 return ParseIntelMemOperand(/*SegReg=*/0, ImmDisp, Start);
1324 if (!ParseRegister(RegNo, Start, End)) {
1325 // If this is a segment register followed by a ':', then this is the start
1326 // of a memory reference, otherwise this is a normal register reference.
1327 if (getLexer().isNot(AsmToken::Colon))
1328 return X86Operand::CreateReg(RegNo, Start, End);
1330 getParser().Lex(); // Eat the colon.
1331 return ParseIntelMemOperand(/*SegReg=*/RegNo, /*Disp=*/0, Start);
1335 return ParseIntelMemOperand(/*SegReg=*/0, /*Disp=*/0, Start);
1338 X86Operand *X86AsmParser::ParseATTOperand() {
1339 switch (getLexer().getKind()) {
1341 // Parse a memory operand with no segment register.
1342 return ParseMemOperand(0, Parser.getTok().getLoc());
1343 case AsmToken::Percent: {
1344 // Read the register.
1347 if (ParseRegister(RegNo, Start, End)) return 0;
1348 if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
1349 Error(Start, "%eiz and %riz can only be used as index registers",
1350 SMRange(Start, End));
1354 // If this is a segment register followed by a ':', then this is the start
1355 // of a memory reference, otherwise this is a normal register reference.
1356 if (getLexer().isNot(AsmToken::Colon))
1357 return X86Operand::CreateReg(RegNo, Start, End);
1359 getParser().Lex(); // Eat the colon.
1360 return ParseMemOperand(RegNo, Start);
1362 case AsmToken::Dollar: {
1363 // $42 -> immediate.
1364 SMLoc Start = Parser.getTok().getLoc(), End;
1367 if (getParser().parseExpression(Val, End))
1369 return X86Operand::CreateImm(Val, Start, End);
1374 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
1375 /// has already been parsed if present.
1376 X86Operand *X86AsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) {
1378 // We have to disambiguate a parenthesized expression "(4+5)" from the start
1379 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
1380 // only way to do this without lookahead is to eat the '(' and see what is
1382 const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
1383 if (getLexer().isNot(AsmToken::LParen)) {
1385 if (getParser().parseExpression(Disp, ExprEnd)) return 0;
1387 // After parsing the base expression we could either have a parenthesized
1388 // memory address or not. If not, return now. If so, eat the (.
1389 if (getLexer().isNot(AsmToken::LParen)) {
1390 // Unless we have a segment register, treat this as an immediate.
1392 return X86Operand::CreateMem(Disp, MemStart, ExprEnd);
1393 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
1399 // Okay, we have a '('. We don't know if this is an expression or not, but
1400 // so we have to eat the ( to see beyond it.
1401 SMLoc LParenLoc = Parser.getTok().getLoc();
1402 Parser.Lex(); // Eat the '('.
1404 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
1405 // Nothing to do here, fall into the code below with the '(' part of the
1406 // memory operand consumed.
1410 // It must be an parenthesized expression, parse it now.
1411 if (getParser().parseParenExpression(Disp, ExprEnd))
1414 // After parsing the base expression we could either have a parenthesized
1415 // memory address or not. If not, return now. If so, eat the (.
1416 if (getLexer().isNot(AsmToken::LParen)) {
1417 // Unless we have a segment register, treat this as an immediate.
1419 return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd);
1420 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
1428 // If we reached here, then we just ate the ( of the memory operand. Process
1429 // the rest of the memory operand.
1430 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
1433 if (getLexer().is(AsmToken::Percent)) {
1434 SMLoc StartLoc, EndLoc;
1435 if (ParseRegister(BaseReg, StartLoc, EndLoc)) return 0;
1436 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
1437 Error(StartLoc, "eiz and riz can only be used as index registers",
1438 SMRange(StartLoc, EndLoc));
1443 if (getLexer().is(AsmToken::Comma)) {
1444 Parser.Lex(); // Eat the comma.
1445 IndexLoc = Parser.getTok().getLoc();
1447 // Following the comma we should have either an index register, or a scale
1448 // value. We don't support the later form, but we want to parse it
1451 // Not that even though it would be completely consistent to support syntax
1452 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
1453 if (getLexer().is(AsmToken::Percent)) {
1455 if (ParseRegister(IndexReg, L, L)) return 0;
1457 if (getLexer().isNot(AsmToken::RParen)) {
1458 // Parse the scale amount:
1459 // ::= ',' [scale-expression]
1460 if (getLexer().isNot(AsmToken::Comma)) {
1461 Error(Parser.getTok().getLoc(),
1462 "expected comma in scale expression");
1465 Parser.Lex(); // Eat the comma.
1467 if (getLexer().isNot(AsmToken::RParen)) {
1468 SMLoc Loc = Parser.getTok().getLoc();
1471 if (getParser().parseAbsoluteExpression(ScaleVal)){
1472 Error(Loc, "expected scale expression");
1476 // Validate the scale amount.
1477 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){
1478 Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
1481 Scale = (unsigned)ScaleVal;
1484 } else if (getLexer().isNot(AsmToken::RParen)) {
1485 // A scale amount without an index is ignored.
1487 SMLoc Loc = Parser.getTok().getLoc();
1490 if (getParser().parseAbsoluteExpression(Value))
1494 Warning(Loc, "scale factor without index register is ignored");
1499 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
1500 if (getLexer().isNot(AsmToken::RParen)) {
1501 Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
1504 SMLoc MemEnd = Parser.getTok().getEndLoc();
1505 Parser.Lex(); // Eat the ')'.
1507 // If we have both a base register and an index register make sure they are
1508 // both 64-bit or 32-bit registers.
1509 // To support VSIB, IndexReg can be 128-bit or 256-bit registers.
1510 if (BaseReg != 0 && IndexReg != 0) {
1511 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&
1512 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
1513 X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg)) &&
1514 IndexReg != X86::RIZ) {
1515 Error(IndexLoc, "index register is 32-bit, but base register is 64-bit");
1518 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) &&
1519 (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
1520 X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) &&
1521 IndexReg != X86::EIZ){
1522 Error(IndexLoc, "index register is 64-bit, but base register is 32-bit");
1527 return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
1532 ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
1533 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1535 StringRef PatchedName = Name;
1537 // FIXME: Hack to recognize setneb as setne.
1538 if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
1539 PatchedName != "setb" && PatchedName != "setnb")
1540 PatchedName = PatchedName.substr(0, Name.size()-1);
1542 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
1543 const MCExpr *ExtraImmOp = 0;
1544 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
1545 (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
1546 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
1547 bool IsVCMP = PatchedName[0] == 'v';
1548 unsigned SSECCIdx = IsVCMP ? 4 : 3;
1549 unsigned SSEComparisonCode = StringSwitch<unsigned>(
1550 PatchedName.slice(SSECCIdx, PatchedName.size() - 2))
1554 .Case("unord", 0x03)
1559 /* AVX only from here */
1560 .Case("eq_uq", 0x08)
1563 .Case("false", 0x0B)
1564 .Case("neq_oq", 0x0C)
1568 .Case("eq_os", 0x10)
1569 .Case("lt_oq", 0x11)
1570 .Case("le_oq", 0x12)
1571 .Case("unord_s", 0x13)
1572 .Case("neq_us", 0x14)
1573 .Case("nlt_uq", 0x15)
1574 .Case("nle_uq", 0x16)
1575 .Case("ord_s", 0x17)
1576 .Case("eq_us", 0x18)
1577 .Case("nge_uq", 0x19)
1578 .Case("ngt_uq", 0x1A)
1579 .Case("false_os", 0x1B)
1580 .Case("neq_os", 0x1C)
1581 .Case("ge_oq", 0x1D)
1582 .Case("gt_oq", 0x1E)
1583 .Case("true_us", 0x1F)
1585 if (SSEComparisonCode != ~0U && (IsVCMP || SSEComparisonCode < 8)) {
1586 ExtraImmOp = MCConstantExpr::Create(SSEComparisonCode,
1587 getParser().getContext());
1588 if (PatchedName.endswith("ss")) {
1589 PatchedName = IsVCMP ? "vcmpss" : "cmpss";
1590 } else if (PatchedName.endswith("sd")) {
1591 PatchedName = IsVCMP ? "vcmpsd" : "cmpsd";
1592 } else if (PatchedName.endswith("ps")) {
1593 PatchedName = IsVCMP ? "vcmpps" : "cmpps";
1595 assert(PatchedName.endswith("pd") && "Unexpected mnemonic!");
1596 PatchedName = IsVCMP ? "vcmppd" : "cmppd";
1601 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
1603 if (ExtraImmOp && !isParsingIntelSyntax())
1604 Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc));
1606 // Determine whether this is an instruction prefix.
1608 Name == "lock" || Name == "rep" ||
1609 Name == "repe" || Name == "repz" ||
1610 Name == "repne" || Name == "repnz" ||
1611 Name == "rex64" || Name == "data16";
1614 // This does the actual operand parsing. Don't parse any more if we have a
1615 // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we
1616 // just want to parse the "lock" as the first instruction and the "incl" as
1618 if (getLexer().isNot(AsmToken::EndOfStatement) && !isPrefix) {
1620 // Parse '*' modifier.
1621 if (getLexer().is(AsmToken::Star)) {
1622 SMLoc Loc = Parser.getTok().getLoc();
1623 Operands.push_back(X86Operand::CreateToken("*", Loc));
1624 Parser.Lex(); // Eat the star.
1627 // Read the first operand.
1628 if (X86Operand *Op = ParseOperand())
1629 Operands.push_back(Op);
1631 Parser.eatToEndOfStatement();
1635 while (getLexer().is(AsmToken::Comma)) {
1636 Parser.Lex(); // Eat the comma.
1638 // Parse and remember the operand.
1639 if (X86Operand *Op = ParseOperand())
1640 Operands.push_back(Op);
1642 Parser.eatToEndOfStatement();
1647 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1648 SMLoc Loc = getLexer().getLoc();
1649 Parser.eatToEndOfStatement();
1650 return Error(Loc, "unexpected token in argument list");
1654 if (getLexer().is(AsmToken::EndOfStatement))
1655 Parser.Lex(); // Consume the EndOfStatement
1656 else if (isPrefix && getLexer().is(AsmToken::Slash))
1657 Parser.Lex(); // Consume the prefix separator Slash
1659 if (ExtraImmOp && isParsingIntelSyntax())
1660 Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc));
1662 // This is a terrible hack to handle "out[bwl]? %al, (%dx)" ->
1663 // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
1664 // documented form in various unofficial manuals, so a lot of code uses it.
1665 if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
1666 Operands.size() == 3) {
1667 X86Operand &Op = *(X86Operand*)Operands.back();
1668 if (Op.isMem() && Op.Mem.SegReg == 0 &&
1669 isa<MCConstantExpr>(Op.Mem.Disp) &&
1670 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
1671 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
1672 SMLoc Loc = Op.getEndLoc();
1673 Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
1677 // Same hack for "in[bwl]? (%dx), %al" -> "inb %dx, %al".
1678 if ((Name == "inb" || Name == "inw" || Name == "inl" || Name == "in") &&
1679 Operands.size() == 3) {
1680 X86Operand &Op = *(X86Operand*)Operands.begin()[1];
1681 if (Op.isMem() && Op.Mem.SegReg == 0 &&
1682 isa<MCConstantExpr>(Op.Mem.Disp) &&
1683 cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
1684 Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
1685 SMLoc Loc = Op.getEndLoc();
1686 Operands.begin()[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
1690 // Transform "ins[bwl] %dx, %es:(%edi)" into "ins[bwl]"
1691 if (Name.startswith("ins") && Operands.size() == 3 &&
1692 (Name == "insb" || Name == "insw" || Name == "insl")) {
1693 X86Operand &Op = *(X86Operand*)Operands.begin()[1];
1694 X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
1695 if (Op.isReg() && Op.getReg() == X86::DX && isDstOp(Op2)) {
1696 Operands.pop_back();
1697 Operands.pop_back();
1703 // Transform "outs[bwl] %ds:(%esi), %dx" into "out[bwl]"
1704 if (Name.startswith("outs") && Operands.size() == 3 &&
1705 (Name == "outsb" || Name == "outsw" || Name == "outsl")) {
1706 X86Operand &Op = *(X86Operand*)Operands.begin()[1];
1707 X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
1708 if (isSrcOp(Op) && Op2.isReg() && Op2.getReg() == X86::DX) {
1709 Operands.pop_back();
1710 Operands.pop_back();
1716 // Transform "movs[bwl] %ds:(%esi), %es:(%edi)" into "movs[bwl]"
1717 if (Name.startswith("movs") && Operands.size() == 3 &&
1718 (Name == "movsb" || Name == "movsw" || Name == "movsl" ||
1719 (is64BitMode() && Name == "movsq"))) {
1720 X86Operand &Op = *(X86Operand*)Operands.begin()[1];
1721 X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
1722 if (isSrcOp(Op) && isDstOp(Op2)) {
1723 Operands.pop_back();
1724 Operands.pop_back();
1729 // Transform "lods[bwl] %ds:(%esi),{%al,%ax,%eax,%rax}" into "lods[bwl]"
1730 if (Name.startswith("lods") && Operands.size() == 3 &&
1731 (Name == "lods" || Name == "lodsb" || Name == "lodsw" ||
1732 Name == "lodsl" || (is64BitMode() && Name == "lodsq"))) {
1733 X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
1734 X86Operand *Op2 = static_cast<X86Operand*>(Operands[2]);
1735 if (isSrcOp(*Op1) && Op2->isReg()) {
1737 unsigned reg = Op2->getReg();
1738 bool isLods = Name == "lods";
1739 if (reg == X86::AL && (isLods || Name == "lodsb"))
1741 else if (reg == X86::AX && (isLods || Name == "lodsw"))
1743 else if (reg == X86::EAX && (isLods || Name == "lodsl"))
1745 else if (reg == X86::RAX && (isLods || Name == "lodsq"))
1750 Operands.pop_back();
1751 Operands.pop_back();
1755 static_cast<X86Operand*>(Operands[0])->setTokenValue(ins);
1759 // Transform "stos[bwl] {%al,%ax,%eax,%rax},%es:(%edi)" into "stos[bwl]"
1760 if (Name.startswith("stos") && Operands.size() == 3 &&
1761 (Name == "stos" || Name == "stosb" || Name == "stosw" ||
1762 Name == "stosl" || (is64BitMode() && Name == "stosq"))) {
1763 X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
1764 X86Operand *Op2 = static_cast<X86Operand*>(Operands[2]);
1765 if (isDstOp(*Op2) && Op1->isReg()) {
1767 unsigned reg = Op1->getReg();
1768 bool isStos = Name == "stos";
1769 if (reg == X86::AL && (isStos || Name == "stosb"))
1771 else if (reg == X86::AX && (isStos || Name == "stosw"))
1773 else if (reg == X86::EAX && (isStos || Name == "stosl"))
1775 else if (reg == X86::RAX && (isStos || Name == "stosq"))
1780 Operands.pop_back();
1781 Operands.pop_back();
1785 static_cast<X86Operand*>(Operands[0])->setTokenValue(ins);
1790 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>. Canonicalize to
1792 if ((Name.startswith("shr") || Name.startswith("sar") ||
1793 Name.startswith("shl") || Name.startswith("sal") ||
1794 Name.startswith("rcl") || Name.startswith("rcr") ||
1795 Name.startswith("rol") || Name.startswith("ror")) &&
1796 Operands.size() == 3) {
1797 if (isParsingIntelSyntax()) {
1799 X86Operand *Op1 = static_cast<X86Operand*>(Operands[2]);
1800 if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
1801 cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) {
1803 Operands.pop_back();
1806 X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
1807 if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
1808 cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) {
1810 Operands.erase(Operands.begin() + 1);
1815 // Transforms "int $3" into "int3" as a size optimization. We can't write an
1816 // instalias with an immediate operand yet.
1817 if (Name == "int" && Operands.size() == 2) {
1818 X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
1819 if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
1820 cast<MCConstantExpr>(Op1->getImm())->getValue() == 3) {
1822 Operands.erase(Operands.begin() + 1);
1823 static_cast<X86Operand*>(Operands[0])->setTokenValue("int3");
1830 static bool convertToSExti8(MCInst &Inst, unsigned Opcode, unsigned Reg,
1833 TmpInst.setOpcode(Opcode);
1835 TmpInst.addOperand(MCOperand::CreateReg(Reg));
1836 TmpInst.addOperand(MCOperand::CreateReg(Reg));
1837 TmpInst.addOperand(Inst.getOperand(0));
1842 static bool convert16i16to16ri8(MCInst &Inst, unsigned Opcode,
1843 bool isCmp = false) {
1844 if (!Inst.getOperand(0).isImm() ||
1845 !isImmSExti16i8Value(Inst.getOperand(0).getImm()))
1848 return convertToSExti8(Inst, Opcode, X86::AX, isCmp);
1851 static bool convert32i32to32ri8(MCInst &Inst, unsigned Opcode,
1852 bool isCmp = false) {
1853 if (!Inst.getOperand(0).isImm() ||
1854 !isImmSExti32i8Value(Inst.getOperand(0).getImm()))
1857 return convertToSExti8(Inst, Opcode, X86::EAX, isCmp);
1860 static bool convert64i32to64ri8(MCInst &Inst, unsigned Opcode,
1861 bool isCmp = false) {
1862 if (!Inst.getOperand(0).isImm() ||
1863 !isImmSExti64i8Value(Inst.getOperand(0).getImm()))
1866 return convertToSExti8(Inst, Opcode, X86::RAX, isCmp);
1870 processInstruction(MCInst &Inst,
1871 const SmallVectorImpl<MCParsedAsmOperand*> &Ops) {
1872 switch (Inst.getOpcode()) {
1873 default: return false;
1874 case X86::AND16i16: return convert16i16to16ri8(Inst, X86::AND16ri8);
1875 case X86::AND32i32: return convert32i32to32ri8(Inst, X86::AND32ri8);
1876 case X86::AND64i32: return convert64i32to64ri8(Inst, X86::AND64ri8);
1877 case X86::XOR16i16: return convert16i16to16ri8(Inst, X86::XOR16ri8);
1878 case X86::XOR32i32: return convert32i32to32ri8(Inst, X86::XOR32ri8);
1879 case X86::XOR64i32: return convert64i32to64ri8(Inst, X86::XOR64ri8);
1880 case X86::OR16i16: return convert16i16to16ri8(Inst, X86::OR16ri8);
1881 case X86::OR32i32: return convert32i32to32ri8(Inst, X86::OR32ri8);
1882 case X86::OR64i32: return convert64i32to64ri8(Inst, X86::OR64ri8);
1883 case X86::CMP16i16: return convert16i16to16ri8(Inst, X86::CMP16ri8, true);
1884 case X86::CMP32i32: return convert32i32to32ri8(Inst, X86::CMP32ri8, true);
1885 case X86::CMP64i32: return convert64i32to64ri8(Inst, X86::CMP64ri8, true);
1886 case X86::ADD16i16: return convert16i16to16ri8(Inst, X86::ADD16ri8);
1887 case X86::ADD32i32: return convert32i32to32ri8(Inst, X86::ADD32ri8);
1888 case X86::ADD64i32: return convert64i32to64ri8(Inst, X86::ADD64ri8);
1889 case X86::SUB16i16: return convert16i16to16ri8(Inst, X86::SUB16ri8);
1890 case X86::SUB32i32: return convert32i32to32ri8(Inst, X86::SUB32ri8);
1891 case X86::SUB64i32: return convert64i32to64ri8(Inst, X86::SUB64ri8);
1892 case X86::ADC16i16: return convert16i16to16ri8(Inst, X86::ADC16ri8);
1893 case X86::ADC32i32: return convert32i32to32ri8(Inst, X86::ADC32ri8);
1894 case X86::ADC64i32: return convert64i32to64ri8(Inst, X86::ADC64ri8);
1895 case X86::SBB16i16: return convert16i16to16ri8(Inst, X86::SBB16ri8);
1896 case X86::SBB32i32: return convert32i32to32ri8(Inst, X86::SBB32ri8);
1897 case X86::SBB64i32: return convert64i32to64ri8(Inst, X86::SBB64ri8);
1901 static const char *getSubtargetFeatureName(unsigned Val);
1903 MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1904 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1905 MCStreamer &Out, unsigned &ErrorInfo,
1906 bool MatchingInlineAsm) {
1907 assert(!Operands.empty() && "Unexpect empty operand list!");
1908 X86Operand *Op = static_cast<X86Operand*>(Operands[0]);
1909 assert(Op->isToken() && "Leading operand should always be a mnemonic!");
1910 ArrayRef<SMRange> EmptyRanges = ArrayRef<SMRange>();
1912 // First, handle aliases that expand to multiple instructions.
1913 // FIXME: This should be replaced with a real .td file alias mechanism.
1914 // Also, MatchInstructionImpl should actually *do* the EmitInstruction
1916 if (Op->getToken() == "fstsw" || Op->getToken() == "fstcw" ||
1917 Op->getToken() == "fstsww" || Op->getToken() == "fstcww" ||
1918 Op->getToken() == "finit" || Op->getToken() == "fsave" ||
1919 Op->getToken() == "fstenv" || Op->getToken() == "fclex") {
1921 Inst.setOpcode(X86::WAIT);
1923 if (!MatchingInlineAsm)
1924 Out.EmitInstruction(Inst);
1927 StringSwitch<const char*>(Op->getToken())
1928 .Case("finit", "fninit")
1929 .Case("fsave", "fnsave")
1930 .Case("fstcw", "fnstcw")
1931 .Case("fstcww", "fnstcw")
1932 .Case("fstenv", "fnstenv")
1933 .Case("fstsw", "fnstsw")
1934 .Case("fstsww", "fnstsw")
1935 .Case("fclex", "fnclex")
1937 assert(Repl && "Unknown wait-prefixed instruction");
1939 Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
1942 bool WasOriginallyInvalidOperand = false;
1945 // First, try a direct match.
1946 switch (MatchInstructionImpl(Operands, Inst,
1947 ErrorInfo, MatchingInlineAsm,
1948 isParsingIntelSyntax())) {
1951 // Some instructions need post-processing to, for example, tweak which
1952 // encoding is selected. Loop on it while changes happen so the
1953 // individual transformations can chain off each other.
1954 if (!MatchingInlineAsm)
1955 while (processInstruction(Inst, Operands))
1959 if (!MatchingInlineAsm)
1960 Out.EmitInstruction(Inst);
1961 Opcode = Inst.getOpcode();
1963 case Match_MissingFeature: {
1964 assert(ErrorInfo && "Unknown missing feature!");
1965 // Special case the error message for the very common case where only
1966 // a single subtarget feature is missing.
1967 std::string Msg = "instruction requires:";
1969 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
1970 if (ErrorInfo & Mask) {
1972 Msg += getSubtargetFeatureName(ErrorInfo & Mask);
1976 return Error(IDLoc, Msg, EmptyRanges, MatchingInlineAsm);
1978 case Match_InvalidOperand:
1979 WasOriginallyInvalidOperand = true;
1981 case Match_MnemonicFail:
1985 // FIXME: Ideally, we would only attempt suffix matches for things which are
1986 // valid prefixes, and we could just infer the right unambiguous
1987 // type. However, that requires substantially more matcher support than the
1990 // Change the operand to point to a temporary token.
1991 StringRef Base = Op->getToken();
1992 SmallString<16> Tmp;
1995 Op->setTokenValue(Tmp.str());
1997 // If this instruction starts with an 'f', then it is a floating point stack
1998 // instruction. These come in up to three forms for 32-bit, 64-bit, and
1999 // 80-bit floating point, which use the suffixes s,l,t respectively.
2001 // Otherwise, we assume that this may be an integer instruction, which comes
2002 // in 8/16/32/64-bit forms using the b,w,l,q suffixes respectively.
2003 const char *Suffixes = Base[0] != 'f' ? "bwlq" : "slt\0";
2005 // Check for the various suffix matches.
2006 Tmp[Base.size()] = Suffixes[0];
2007 unsigned ErrorInfoIgnore;
2008 unsigned ErrorInfoMissingFeature = 0; // Init suppresses compiler warnings.
2009 unsigned Match1, Match2, Match3, Match4;
2011 Match1 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2012 isParsingIntelSyntax());
2013 // If this returned as a missing feature failure, remember that.
2014 if (Match1 == Match_MissingFeature)
2015 ErrorInfoMissingFeature = ErrorInfoIgnore;
2016 Tmp[Base.size()] = Suffixes[1];
2017 Match2 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2018 isParsingIntelSyntax());
2019 // If this returned as a missing feature failure, remember that.
2020 if (Match2 == Match_MissingFeature)
2021 ErrorInfoMissingFeature = ErrorInfoIgnore;
2022 Tmp[Base.size()] = Suffixes[2];
2023 Match3 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2024 isParsingIntelSyntax());
2025 // If this returned as a missing feature failure, remember that.
2026 if (Match3 == Match_MissingFeature)
2027 ErrorInfoMissingFeature = ErrorInfoIgnore;
2028 Tmp[Base.size()] = Suffixes[3];
2029 Match4 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2030 isParsingIntelSyntax());
2031 // If this returned as a missing feature failure, remember that.
2032 if (Match4 == Match_MissingFeature)
2033 ErrorInfoMissingFeature = ErrorInfoIgnore;
2035 // Restore the old token.
2036 Op->setTokenValue(Base);
2038 // If exactly one matched, then we treat that as a successful match (and the
2039 // instruction will already have been filled in correctly, since the failing
2040 // matches won't have modified it).
2041 unsigned NumSuccessfulMatches =
2042 (Match1 == Match_Success) + (Match2 == Match_Success) +
2043 (Match3 == Match_Success) + (Match4 == Match_Success);
2044 if (NumSuccessfulMatches == 1) {
2046 if (!MatchingInlineAsm)
2047 Out.EmitInstruction(Inst);
2048 Opcode = Inst.getOpcode();
2052 // Otherwise, the match failed, try to produce a decent error message.
2054 // If we had multiple suffix matches, then identify this as an ambiguous
2056 if (NumSuccessfulMatches > 1) {
2058 unsigned NumMatches = 0;
2059 if (Match1 == Match_Success) MatchChars[NumMatches++] = Suffixes[0];
2060 if (Match2 == Match_Success) MatchChars[NumMatches++] = Suffixes[1];
2061 if (Match3 == Match_Success) MatchChars[NumMatches++] = Suffixes[2];
2062 if (Match4 == Match_Success) MatchChars[NumMatches++] = Suffixes[3];
2064 SmallString<126> Msg;
2065 raw_svector_ostream OS(Msg);
2066 OS << "ambiguous instructions require an explicit suffix (could be ";
2067 for (unsigned i = 0; i != NumMatches; ++i) {
2070 if (i + 1 == NumMatches)
2072 OS << "'" << Base << MatchChars[i] << "'";
2075 Error(IDLoc, OS.str(), EmptyRanges, MatchingInlineAsm);
2079 // Okay, we know that none of the variants matched successfully.
2081 // If all of the instructions reported an invalid mnemonic, then the original
2082 // mnemonic was invalid.
2083 if ((Match1 == Match_MnemonicFail) && (Match2 == Match_MnemonicFail) &&
2084 (Match3 == Match_MnemonicFail) && (Match4 == Match_MnemonicFail)) {
2085 if (!WasOriginallyInvalidOperand) {
2086 ArrayRef<SMRange> Ranges = MatchingInlineAsm ? EmptyRanges :
2088 return Error(IDLoc, "invalid instruction mnemonic '" + Base + "'",
2089 Ranges, MatchingInlineAsm);
2092 // Recover location info for the operand if we know which was the problem.
2093 if (ErrorInfo != ~0U) {
2094 if (ErrorInfo >= Operands.size())
2095 return Error(IDLoc, "too few operands for instruction",
2096 EmptyRanges, MatchingInlineAsm);
2098 X86Operand *Operand = (X86Operand*)Operands[ErrorInfo];
2099 if (Operand->getStartLoc().isValid()) {
2100 SMRange OperandRange = Operand->getLocRange();
2101 return Error(Operand->getStartLoc(), "invalid operand for instruction",
2102 OperandRange, MatchingInlineAsm);
2106 return Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2110 // If one instruction matched with a missing feature, report this as a
2112 if ((Match1 == Match_MissingFeature) + (Match2 == Match_MissingFeature) +
2113 (Match3 == Match_MissingFeature) + (Match4 == Match_MissingFeature) == 1){
2114 std::string Msg = "instruction requires:";
2116 for (unsigned i = 0; i < (sizeof(ErrorInfoMissingFeature)*8-1); ++i) {
2117 if (ErrorInfoMissingFeature & Mask) {
2119 Msg += getSubtargetFeatureName(ErrorInfoMissingFeature & Mask);
2123 return Error(IDLoc, Msg, EmptyRanges, MatchingInlineAsm);
2126 // If one instruction matched with an invalid operand, report this as an
2128 if ((Match1 == Match_InvalidOperand) + (Match2 == Match_InvalidOperand) +
2129 (Match3 == Match_InvalidOperand) + (Match4 == Match_InvalidOperand) == 1){
2130 Error(IDLoc, "invalid operand for instruction", EmptyRanges,
2135 // If all of these were an outright failure, report it in a useless way.
2136 Error(IDLoc, "unknown use of instruction mnemonic without a size suffix",
2137 EmptyRanges, MatchingInlineAsm);
2142 bool X86AsmParser::ParseDirective(AsmToken DirectiveID) {
2143 StringRef IDVal = DirectiveID.getIdentifier();
2144 if (IDVal == ".word")
2145 return ParseDirectiveWord(2, DirectiveID.getLoc());
2146 else if (IDVal.startswith(".code"))
2147 return ParseDirectiveCode(IDVal, DirectiveID.getLoc());
2148 else if (IDVal.startswith(".att_syntax")) {
2149 getParser().setAssemblerDialect(0);
2151 } else if (IDVal.startswith(".intel_syntax")) {
2152 getParser().setAssemblerDialect(1);
2153 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2154 if(Parser.getTok().getString() == "noprefix") {
2155 // FIXME : Handle noprefix
2165 /// ParseDirectiveWord
2166 /// ::= .word [ expression (, expression)* ]
2167 bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2168 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2170 const MCExpr *Value;
2171 if (getParser().parseExpression(Value))
2174 getParser().getStreamer().EmitValue(Value, Size);
2176 if (getLexer().is(AsmToken::EndOfStatement))
2179 // FIXME: Improve diagnostic.
2180 if (getLexer().isNot(AsmToken::Comma))
2181 return Error(L, "unexpected token in directive");
2190 /// ParseDirectiveCode
2191 /// ::= .code32 | .code64
2192 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
2193 if (IDVal == ".code32") {
2195 if (is64BitMode()) {
2197 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2199 } else if (IDVal == ".code64") {
2201 if (!is64BitMode()) {
2203 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
2206 return Error(L, "unexpected directive " + IDVal);
2212 // Force static initialization.
2213 extern "C" void LLVMInitializeX86AsmParser() {
2214 RegisterMCAsmParser<X86AsmParser> X(TheX86_32Target);
2215 RegisterMCAsmParser<X86AsmParser> Y(TheX86_64Target);
2218 #define GET_REGISTER_MATCHER
2219 #define GET_MATCHER_IMPLEMENTATION
2220 #define GET_SUBTARGET_FEATURE_NAME
2221 #include "X86GenAsmMatcher.inc"