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 "llvm/Target/TargetAsmParser.h"
12 #include "X86Subtarget.h"
13 #include "llvm/ADT/SmallVector.h"
14 #include "llvm/ADT/StringSwitch.h"
15 #include "llvm/ADT/Twine.h"
16 #include "llvm/MC/MCStreamer.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/Support/SourceMgr.h"
23 #include "llvm/Target/TargetRegistry.h"
24 #include "llvm/Target/TargetAsmParser.h"
30 class X86ATTAsmParser : public TargetAsmParser {
38 MCAsmParser &getParser() const { return Parser; }
40 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
42 void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
44 bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
46 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
48 X86Operand *ParseOperand();
49 X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
51 bool ParseDirectiveWord(unsigned Size, SMLoc L);
53 bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
56 /// @name Auto-generated Matcher Functions
59 unsigned ComputeAvailableFeatures(const X86Subtarget *Subtarget) const;
61 bool MatchInstructionImpl(
62 const SmallVectorImpl<MCParsedAsmOperand*> &Operands, MCInst &Inst);
67 X86ATTAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &TM)
68 : TargetAsmParser(T), Parser(_Parser), TM(TM) {
70 // Initialize the set of available features.
71 setAvailableFeatures(ComputeAvailableFeatures(
72 &TM.getSubtarget<X86Subtarget>()));
75 virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
76 SmallVectorImpl<MCParsedAsmOperand*> &Operands);
78 virtual bool ParseDirective(AsmToken DirectiveID);
81 class X86_32ATTAsmParser : public X86ATTAsmParser {
83 X86_32ATTAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &TM)
84 : X86ATTAsmParser(T, _Parser, TM) {
89 class X86_64ATTAsmParser : public X86ATTAsmParser {
91 X86_64ATTAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &TM)
92 : X86ATTAsmParser(T, _Parser, TM) {
97 } // end anonymous namespace
99 /// @name Auto-generated Match Functions
102 static unsigned MatchRegisterName(StringRef Name);
108 /// X86Operand - Instances of this class represent a parsed X86 machine
110 struct X86Operand : public MCParsedAsmOperand {
118 SMLoc StartLoc, EndLoc;
143 X86Operand(KindTy K, SMLoc Start, SMLoc End)
144 : Kind(K), StartLoc(Start), EndLoc(End) {}
146 /// getStartLoc - Get the location of the first token of this operand.
147 SMLoc getStartLoc() const { return StartLoc; }
148 /// getEndLoc - Get the location of the last token of this operand.
149 SMLoc getEndLoc() const { return EndLoc; }
151 StringRef getToken() const {
152 assert(Kind == Token && "Invalid access!");
153 return StringRef(Tok.Data, Tok.Length);
155 void setTokenValue(StringRef Value) {
156 assert(Kind == Token && "Invalid access!");
157 Tok.Data = Value.data();
158 Tok.Length = Value.size();
161 unsigned getReg() const {
162 assert(Kind == Register && "Invalid access!");
166 const MCExpr *getImm() const {
167 assert(Kind == Immediate && "Invalid access!");
171 const MCExpr *getMemDisp() const {
172 assert(Kind == Memory && "Invalid access!");
175 unsigned getMemSegReg() const {
176 assert(Kind == Memory && "Invalid access!");
179 unsigned getMemBaseReg() const {
180 assert(Kind == Memory && "Invalid access!");
183 unsigned getMemIndexReg() const {
184 assert(Kind == Memory && "Invalid access!");
187 unsigned getMemScale() const {
188 assert(Kind == Memory && "Invalid access!");
192 bool isToken() const {return Kind == Token; }
194 bool isImm() const { return Kind == Immediate; }
196 bool isImmSExti16i8() const {
200 // If this isn't a constant expr, just assume it fits and let relaxation
202 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
206 // Otherwise, check the value is in a range that makes sense for this
208 uint64_t Value = CE->getValue();
209 return (( Value <= 0x000000000000007FULL)||
210 (0x000000000000FF80ULL <= Value && Value <= 0x000000000000FFFFULL)||
211 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
213 bool isImmSExti32i8() const {
217 // If this isn't a constant expr, just assume it fits and let relaxation
219 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
223 // Otherwise, check the value is in a range that makes sense for this
225 uint64_t Value = CE->getValue();
226 return (( Value <= 0x000000000000007FULL)||
227 (0x00000000FFFFFF80ULL <= Value && Value <= 0x00000000FFFFFFFFULL)||
228 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
230 bool isImmSExti64i8() const {
234 // If this isn't a constant expr, just assume it fits and let relaxation
236 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
240 // Otherwise, check the value is in a range that makes sense for this
242 uint64_t Value = CE->getValue();
243 return (( Value <= 0x000000000000007FULL)||
244 (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
246 bool isImmSExti64i32() const {
250 // If this isn't a constant expr, just assume it fits and let relaxation
252 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
256 // Otherwise, check the value is in a range that makes sense for this
258 uint64_t Value = CE->getValue();
259 return (( Value <= 0x000000007FFFFFFFULL)||
260 (0xFFFFFFFF80000000ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL));
263 bool isMem() const { return Kind == Memory; }
265 bool isAbsMem() const {
266 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
267 !getMemIndexReg() && getMemScale() == 1;
270 bool isNoSegMem() const {
271 return Kind == Memory && !getMemSegReg();
274 bool isReg() const { return Kind == Register; }
276 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
277 // Add as immediates when possible.
278 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
279 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
281 Inst.addOperand(MCOperand::CreateExpr(Expr));
284 void addRegOperands(MCInst &Inst, unsigned N) const {
285 assert(N == 1 && "Invalid number of operands!");
286 Inst.addOperand(MCOperand::CreateReg(getReg()));
289 void addImmOperands(MCInst &Inst, unsigned N) const {
290 assert(N == 1 && "Invalid number of operands!");
291 addExpr(Inst, getImm());
294 void addMemOperands(MCInst &Inst, unsigned N) const {
295 assert((N == 5) && "Invalid number of operands!");
296 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
297 Inst.addOperand(MCOperand::CreateImm(getMemScale()));
298 Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
299 addExpr(Inst, getMemDisp());
300 Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
303 void addAbsMemOperands(MCInst &Inst, unsigned N) const {
304 assert((N == 1) && "Invalid number of operands!");
305 Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
308 void addNoSegMemOperands(MCInst &Inst, unsigned N) const {
309 assert((N == 4) && "Invalid number of operands!");
310 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
311 Inst.addOperand(MCOperand::CreateImm(getMemScale()));
312 Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
313 addExpr(Inst, getMemDisp());
316 static X86Operand *CreateToken(StringRef Str, SMLoc Loc) {
317 X86Operand *Res = new X86Operand(Token, Loc, Loc);
318 Res->Tok.Data = Str.data();
319 Res->Tok.Length = Str.size();
323 static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc) {
324 X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc);
325 Res->Reg.RegNo = RegNo;
329 static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc){
330 X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc);
335 /// Create an absolute memory operand.
336 static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc,
338 X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
340 Res->Mem.Disp = Disp;
341 Res->Mem.BaseReg = 0;
342 Res->Mem.IndexReg = 0;
347 /// Create a generalized memory operand.
348 static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp,
349 unsigned BaseReg, unsigned IndexReg,
350 unsigned Scale, SMLoc StartLoc, SMLoc EndLoc) {
351 // We should never just have a displacement, that should be parsed as an
352 // absolute memory operand.
353 assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
355 // The scale should always be one of {1,2,4,8}.
356 assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
358 X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
359 Res->Mem.SegReg = SegReg;
360 Res->Mem.Disp = Disp;
361 Res->Mem.BaseReg = BaseReg;
362 Res->Mem.IndexReg = IndexReg;
363 Res->Mem.Scale = Scale;
368 } // end anonymous namespace.
371 bool X86ATTAsmParser::ParseRegister(unsigned &RegNo,
372 SMLoc &StartLoc, SMLoc &EndLoc) {
374 const AsmToken &TokPercent = Parser.getTok();
375 assert(TokPercent.is(AsmToken::Percent) && "Invalid token kind!");
376 StartLoc = TokPercent.getLoc();
377 Parser.Lex(); // Eat percent token.
379 const AsmToken &Tok = Parser.getTok();
380 if (Tok.isNot(AsmToken::Identifier))
381 return Error(Tok.getLoc(), "invalid register name");
383 // FIXME: Validate register for the current architecture; we have to do
384 // validation later, so maybe there is no need for this here.
385 RegNo = MatchRegisterName(Tok.getString());
387 // FIXME: This should be done using Requires<In32BitMode> and
388 // Requires<In64BitMode> so "eiz" usage in 64-bit instructions
389 // can be also checked.
390 if (RegNo == X86::RIZ && !Is64Bit)
391 return Error(Tok.getLoc(), "riz register in 64-bit mode only");
393 // Parse %st(1) and "%st" as "%st(0)"
394 if (RegNo == 0 && Tok.getString() == "st") {
396 EndLoc = Tok.getLoc();
397 Parser.Lex(); // Eat 'st'
399 // Check to see if we have '(4)' after %st.
400 if (getLexer().isNot(AsmToken::LParen))
405 const AsmToken &IntTok = Parser.getTok();
406 if (IntTok.isNot(AsmToken::Integer))
407 return Error(IntTok.getLoc(), "expected stack index");
408 switch (IntTok.getIntVal()) {
409 case 0: RegNo = X86::ST0; break;
410 case 1: RegNo = X86::ST1; break;
411 case 2: RegNo = X86::ST2; break;
412 case 3: RegNo = X86::ST3; break;
413 case 4: RegNo = X86::ST4; break;
414 case 5: RegNo = X86::ST5; break;
415 case 6: RegNo = X86::ST6; break;
416 case 7: RegNo = X86::ST7; break;
417 default: return Error(IntTok.getLoc(), "invalid stack index");
420 if (getParser().Lex().isNot(AsmToken::RParen))
421 return Error(Parser.getTok().getLoc(), "expected ')'");
423 EndLoc = Tok.getLoc();
424 Parser.Lex(); // Eat ')'
428 // If this is "db[0-7]", match it as an alias
430 if (RegNo == 0 && Tok.getString().size() == 3 &&
431 Tok.getString().startswith("db")) {
432 switch (Tok.getString()[2]) {
433 case '0': RegNo = X86::DR0; break;
434 case '1': RegNo = X86::DR1; break;
435 case '2': RegNo = X86::DR2; break;
436 case '3': RegNo = X86::DR3; break;
437 case '4': RegNo = X86::DR4; break;
438 case '5': RegNo = X86::DR5; break;
439 case '6': RegNo = X86::DR6; break;
440 case '7': RegNo = X86::DR7; break;
444 EndLoc = Tok.getLoc();
445 Parser.Lex(); // Eat it.
451 return Error(Tok.getLoc(), "invalid register name");
453 EndLoc = Tok.getLoc();
454 Parser.Lex(); // Eat identifier token.
458 X86Operand *X86ATTAsmParser::ParseOperand() {
459 switch (getLexer().getKind()) {
461 // Parse a memory operand with no segment register.
462 return ParseMemOperand(0, Parser.getTok().getLoc());
463 case AsmToken::Percent: {
464 // Read the register.
467 if (ParseRegister(RegNo, Start, End)) return 0;
468 if (RegNo == X86::EIZ || RegNo == X86::RIZ) {
469 Error(Start, "eiz and riz can only be used as index registers");
473 // If this is a segment register followed by a ':', then this is the start
474 // of a memory reference, otherwise this is a normal register reference.
475 if (getLexer().isNot(AsmToken::Colon))
476 return X86Operand::CreateReg(RegNo, Start, End);
479 getParser().Lex(); // Eat the colon.
480 return ParseMemOperand(RegNo, Start);
482 case AsmToken::Dollar: {
484 SMLoc Start = Parser.getTok().getLoc(), End;
487 if (getParser().ParseExpression(Val, End))
489 return X86Operand::CreateImm(Val, Start, End);
494 /// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
495 /// has already been parsed if present.
496 X86Operand *X86ATTAsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) {
498 // We have to disambiguate a parenthesized expression "(4+5)" from the start
499 // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The
500 // only way to do this without lookahead is to eat the '(' and see what is
502 const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
503 if (getLexer().isNot(AsmToken::LParen)) {
505 if (getParser().ParseExpression(Disp, ExprEnd)) return 0;
507 // After parsing the base expression we could either have a parenthesized
508 // memory address or not. If not, return now. If so, eat the (.
509 if (getLexer().isNot(AsmToken::LParen)) {
510 // Unless we have a segment register, treat this as an immediate.
512 return X86Operand::CreateMem(Disp, MemStart, ExprEnd);
513 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
519 // Okay, we have a '('. We don't know if this is an expression or not, but
520 // so we have to eat the ( to see beyond it.
521 SMLoc LParenLoc = Parser.getTok().getLoc();
522 Parser.Lex(); // Eat the '('.
524 if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
525 // Nothing to do here, fall into the code below with the '(' part of the
526 // memory operand consumed.
530 // It must be an parenthesized expression, parse it now.
531 if (getParser().ParseParenExpression(Disp, ExprEnd))
534 // After parsing the base expression we could either have a parenthesized
535 // memory address or not. If not, return now. If so, eat the (.
536 if (getLexer().isNot(AsmToken::LParen)) {
537 // Unless we have a segment register, treat this as an immediate.
539 return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd);
540 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
548 // If we reached here, then we just ate the ( of the memory operand. Process
549 // the rest of the memory operand.
550 unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
552 if (getLexer().is(AsmToken::Percent)) {
554 if (ParseRegister(BaseReg, L, L)) return 0;
555 if (BaseReg == X86::EIZ || BaseReg == X86::RIZ) {
556 Error(L, "eiz and riz can only be used as index registers");
561 if (getLexer().is(AsmToken::Comma)) {
562 Parser.Lex(); // Eat the comma.
564 // Following the comma we should have either an index register, or a scale
565 // value. We don't support the later form, but we want to parse it
568 // Not that even though it would be completely consistent to support syntax
569 // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
570 if (getLexer().is(AsmToken::Percent)) {
572 if (ParseRegister(IndexReg, L, L)) return 0;
574 if (getLexer().isNot(AsmToken::RParen)) {
575 // Parse the scale amount:
576 // ::= ',' [scale-expression]
577 if (getLexer().isNot(AsmToken::Comma)) {
578 Error(Parser.getTok().getLoc(),
579 "expected comma in scale expression");
582 Parser.Lex(); // Eat the comma.
584 if (getLexer().isNot(AsmToken::RParen)) {
585 SMLoc Loc = Parser.getTok().getLoc();
588 if (getParser().ParseAbsoluteExpression(ScaleVal))
591 // Validate the scale amount.
592 if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){
593 Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
596 Scale = (unsigned)ScaleVal;
599 } else if (getLexer().isNot(AsmToken::RParen)) {
600 // Otherwise we have the unsupported form of a scale amount without an
602 SMLoc Loc = Parser.getTok().getLoc();
605 if (getParser().ParseAbsoluteExpression(Value))
608 Error(Loc, "cannot have scale factor without index register");
613 // Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
614 if (getLexer().isNot(AsmToken::RParen)) {
615 Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
618 SMLoc MemEnd = Parser.getTok().getLoc();
619 Parser.Lex(); // Eat the ')'.
621 return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
625 bool X86ATTAsmParser::
626 ParseInstruction(StringRef Name, SMLoc NameLoc,
627 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
628 // The various flavors of pushf and popf use Requires<In32BitMode> and
629 // Requires<In64BitMode>, but the assembler doesn't yet implement that.
630 // For now, just do a manual check to prevent silent misencoding.
633 return Error(NameLoc, "popfl cannot be encoded in 64-bit mode");
634 else if (Name == "pushfl")
635 return Error(NameLoc, "pushfl cannot be encoded in 64-bit mode");
636 else if (Name == "pusha")
637 return Error(NameLoc, "pusha cannot be encoded in 64-bit mode");
640 return Error(NameLoc, "popfq cannot be encoded in 32-bit mode");
641 else if (Name == "pushfq")
642 return Error(NameLoc, "pushfq cannot be encoded in 32-bit mode");
645 // The "Jump if rCX Zero" form jcxz is not allowed in 64-bit mode and
646 // the form jrcxz is not allowed in 32-bit mode.
649 return Error(NameLoc, "jcxz cannot be encoded in 64-bit mode");
652 return Error(NameLoc, "jrcxz cannot be encoded in 32-bit mode");
655 // FIXME: Hack to recognize "sal..." and "rep..." for now. We need a way to
656 // represent alternative syntaxes in the .td file, without requiring
657 // instruction duplication.
658 StringRef PatchedName = StringSwitch<StringRef>(Name)
660 .Case("salb", "shlb")
661 .Case("sall", "shll")
662 .Case("salq", "shlq")
663 .Case("salw", "shlw")
666 .Case("repnz", "repne")
667 .Case("pushf", Is64Bit ? "pushfq" : "pushfl")
668 .Case("popf", Is64Bit ? "popfq" : "popfl")
669 .Case("retl", Is64Bit ? "retl" : "ret")
670 .Case("retq", Is64Bit ? "ret" : "retq")
671 .Case("setz", "sete")
672 .Case("setnz", "setne")
676 // FIXME: in 32-bit mode jcxz requires an AdSize prefix. In 64-bit mode
677 // jecxz requires an AdSize prefix but jecxz does not have a prefix in
679 .Case("jecxz", "jcxz")
680 .Case("jrcxz", "jcxz")
692 .Case("cmovcl", "cmovbl")
693 .Case("cmovcl", "cmovbl")
694 .Case("cmovnal", "cmovbel")
695 .Case("cmovnbl", "cmovael")
696 .Case("cmovnbel", "cmoval")
697 .Case("cmovncl", "cmovael")
698 .Case("cmovngl", "cmovlel")
699 .Case("cmovnl", "cmovgel")
700 .Case("cmovngl", "cmovlel")
701 .Case("cmovngel", "cmovll")
702 .Case("cmovnll", "cmovgel")
703 .Case("cmovnlel", "cmovgl")
704 .Case("cmovnzl", "cmovnel")
705 .Case("cmovzl", "cmovel")
706 .Case("fwait", "wait")
707 .Case("movzx", "movzb")
710 // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
711 const MCExpr *ExtraImmOp = 0;
712 if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
713 (PatchedName.endswith("ss") || PatchedName.endswith("sd") ||
714 PatchedName.endswith("ps") || PatchedName.endswith("pd"))) {
715 bool IsVCMP = PatchedName.startswith("vcmp");
716 unsigned SSECCIdx = IsVCMP ? 4 : 3;
717 unsigned SSEComparisonCode = StringSwitch<unsigned>(
718 PatchedName.slice(SSECCIdx, PatchedName.size() - 2))
731 .Case("neq_oq", 0x0C)
738 .Case("unord_s", 0x13)
739 .Case("neq_us", 0x14)
740 .Case("nlt_uq", 0x15)
741 .Case("nle_uq", 0x16)
744 .Case("nge_uq", 0x19)
745 .Case("ngt_uq", 0x1A)
746 .Case("false_os", 0x1B)
747 .Case("neq_os", 0x1C)
750 .Case("true_us", 0x1F)
752 if (SSEComparisonCode != ~0U) {
753 ExtraImmOp = MCConstantExpr::Create(SSEComparisonCode,
754 getParser().getContext());
755 if (PatchedName.endswith("ss")) {
756 PatchedName = IsVCMP ? "vcmpss" : "cmpss";
757 } else if (PatchedName.endswith("sd")) {
758 PatchedName = IsVCMP ? "vcmpsd" : "cmpsd";
759 } else if (PatchedName.endswith("ps")) {
760 PatchedName = IsVCMP ? "vcmpps" : "cmpps";
762 assert(PatchedName.endswith("pd") && "Unexpected mnemonic!");
763 PatchedName = IsVCMP ? "vcmppd" : "cmppd";
768 // FIXME: Hack to recognize vpclmul<src1_quadword, src2_quadword>dq
769 if (PatchedName.startswith("vpclmul")) {
770 unsigned CLMULQuadWordSelect = StringSwitch<unsigned>(
771 PatchedName.slice(7, PatchedName.size() - 2))
772 .Case("lqlq", 0x00) // src1[63:0], src2[63:0]
773 .Case("hqlq", 0x01) // src1[127:64], src2[63:0]
774 .Case("lqhq", 0x10) // src1[63:0], src2[127:64]
775 .Case("hqhq", 0x11) // src1[127:64], src2[127:64]
777 if (CLMULQuadWordSelect != ~0U) {
778 ExtraImmOp = MCConstantExpr::Create(CLMULQuadWordSelect,
779 getParser().getContext());
780 assert(PatchedName.endswith("dq") && "Unexpected mnemonic!");
781 PatchedName = "vpclmulqdq";
784 Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
787 Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc));
789 if (getLexer().isNot(AsmToken::EndOfStatement)) {
791 // Parse '*' modifier.
792 if (getLexer().is(AsmToken::Star)) {
793 SMLoc Loc = Parser.getTok().getLoc();
794 Operands.push_back(X86Operand::CreateToken("*", Loc));
795 Parser.Lex(); // Eat the star.
798 // Read the first operand.
799 if (X86Operand *Op = ParseOperand())
800 Operands.push_back(Op);
804 while (getLexer().is(AsmToken::Comma)) {
805 Parser.Lex(); // Eat the comma.
807 // Parse and remember the operand.
808 if (X86Operand *Op = ParseOperand())
809 Operands.push_back(Op);
815 // FIXME: Hack to handle recognizing s{hr,ar,hl}? $1.
816 if ((Name.startswith("shr") || Name.startswith("sar") ||
817 Name.startswith("shl")) &&
818 Operands.size() == 3 &&
819 static_cast<X86Operand*>(Operands[1])->isImm() &&
820 isa<MCConstantExpr>(static_cast<X86Operand*>(Operands[1])->getImm()) &&
821 cast<MCConstantExpr>(static_cast<X86Operand*>(Operands[1])->getImm())->getValue() == 1) {
823 Operands.erase(Operands.begin() + 1);
826 // FIXME: Hack to handle "f{mul*,add*,sub*,div*} $op, st(0)" the same as
827 // "f{mul*,add*,sub*,div*} $op"
828 if ((Name.startswith("fmul") || Name.startswith("fadd") ||
829 Name.startswith("fsub") || Name.startswith("fdiv")) &&
830 Operands.size() == 3 &&
831 static_cast<X86Operand*>(Operands[2])->isReg() &&
832 static_cast<X86Operand*>(Operands[2])->getReg() == X86::ST0) {
834 Operands.erase(Operands.begin() + 2);
840 bool X86ATTAsmParser::ParseDirective(AsmToken DirectiveID) {
841 StringRef IDVal = DirectiveID.getIdentifier();
842 if (IDVal == ".word")
843 return ParseDirectiveWord(2, DirectiveID.getLoc());
847 /// ParseDirectiveWord
848 /// ::= .word [ expression (, expression)* ]
849 bool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
850 if (getLexer().isNot(AsmToken::EndOfStatement)) {
853 if (getParser().ParseExpression(Value))
856 getParser().getStreamer().EmitValue(Value, Size, 0 /*addrspace*/);
858 if (getLexer().is(AsmToken::EndOfStatement))
861 // FIXME: Improve diagnostic.
862 if (getLexer().isNot(AsmToken::Comma))
863 return Error(L, "unexpected token in directive");
873 X86ATTAsmParser::MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*>
876 // First, try a direct match.
877 if (!MatchInstructionImpl(Operands, Inst))
880 // Ignore anything which is obviously not a suffix match.
881 if (Operands.size() == 0)
883 X86Operand *Op = static_cast<X86Operand*>(Operands[0]);
884 if (!Op->isToken() || Op->getToken().size() > 15)
887 // FIXME: Ideally, we would only attempt suffix matches for things which are
888 // valid prefixes, and we could just infer the right unambiguous
889 // type. However, that requires substantially more matcher support than the
892 // Change the operand to point to a temporary token.
894 StringRef Base = Op->getToken();
895 memcpy(Tmp, Base.data(), Base.size());
896 Op->setTokenValue(StringRef(Tmp, Base.size() + 1));
898 // Check for the various suffix matches.
899 Tmp[Base.size()] = 'b';
900 bool MatchB = MatchInstructionImpl(Operands, Inst);
901 Tmp[Base.size()] = 'w';
902 bool MatchW = MatchInstructionImpl(Operands, Inst);
903 Tmp[Base.size()] = 'l';
904 bool MatchL = MatchInstructionImpl(Operands, Inst);
905 Tmp[Base.size()] = 'q';
906 bool MatchQ = MatchInstructionImpl(Operands, Inst);
908 // Restore the old token.
909 Op->setTokenValue(Base);
911 // If exactly one matched, then we treat that as a successful match (and the
912 // instruction will already have been filled in correctly, since the failing
913 // matches won't have modified it).
914 if (MatchB + MatchW + MatchL + MatchQ == 3)
917 // Otherwise, the match failed.
922 extern "C" void LLVMInitializeX86AsmLexer();
924 // Force static initialization.
925 extern "C" void LLVMInitializeX86AsmParser() {
926 RegisterAsmParser<X86_32ATTAsmParser> X(TheX86_32Target);
927 RegisterAsmParser<X86_64ATTAsmParser> Y(TheX86_64Target);
928 LLVMInitializeX86AsmLexer();
931 #include "X86GenAsmMatcher.inc"