diff options
Diffstat (limited to 'llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp')
-rw-r--r-- | llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp | 44 |
1 files changed, 31 insertions, 13 deletions
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index 3f135641991..82cc90526bf 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -2414,13 +2414,15 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, } } + unsigned ComparisonCode = ~0U; + // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}. if (PatchedName.startswith("vpcom") && - (PatchedName.endswith("b") || PatchedName.endswith("w") || - PatchedName.endswith("d") || PatchedName.endswith("q"))) { - unsigned CCIdx = PatchedName.drop_back().back() == 'u' ? 2 : 1; - unsigned ComparisonCode = StringSwitch<unsigned>( - PatchedName.slice(5, PatchedName.size() - CCIdx)) + (PatchedName.back() == 'b' || PatchedName.back() == 'w' || + PatchedName.back() == 'd' || PatchedName.back() == 'q')) { + unsigned SuffixSize = PatchedName.drop_back().back() == 'u' ? 2 : 1; + unsigned CC = StringSwitch<unsigned>( + PatchedName.slice(5, PatchedName.size() - SuffixSize)) .Case("lt", 0x0) .Case("le", 0x1) .Case("gt", 0x2) @@ -2430,14 +2432,16 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, .Case("false", 0x6) .Case("true", 0x7) .Default(~0U); - if (ComparisonCode != ~0U) { - Operands.push_back(X86Operand::CreateToken("vpcom", NameLoc)); - - const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode, - getParser().getContext()); - Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc)); - - PatchedName = PatchedName.substr(PatchedName.size() - CCIdx); + if (CC != ~0U) { + switch (PatchedName.back()) { + default: llvm_unreachable("Unexpected character!"); + case 'b': PatchedName = SuffixSize == 2 ? "vpcomub" : "vpcomb"; break; + case 'w': PatchedName = SuffixSize == 2 ? "vpcomuw" : "vpcomw"; break; + case 'd': PatchedName = SuffixSize == 2 ? "vpcomud" : "vpcomd"; break; + case 'q': PatchedName = SuffixSize == 2 ? "vpcomuq" : "vpcomq"; break; + } + // Set up the immediate to push into the operands later. + ComparisonCode = CC; } } @@ -2510,6 +2514,13 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc)); + // Push the immediate if we extracted one from the mnemonic. + if (ComparisonCode != ~0U && !isParsingIntelSyntax()) { + const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode, + getParser().getContext()); + Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc)); + } + // This does the actual operand parsing. Don't parse any more if we have a // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we // just want to parse the "lock" as the first instruction and the "incl" as @@ -2544,6 +2555,13 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, return TokError("unexpected token in argument list"); } + // Push the immediate if we extracted one from the mnemonic. + if (ComparisonCode != ~0U && isParsingIntelSyntax()) { + const MCExpr *ImmOp = MCConstantExpr::create(ComparisonCode, + getParser().getContext()); + Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc)); + } + // Consume the EndOfStatement or the prefix separator Slash if (getLexer().is(AsmToken::EndOfStatement) || (isPrefix && getLexer().is(AsmToken::Slash))) |