[X86] Add support for vex, vex2, vex3, and evex for MASM

For MASM syntax, the prefixes are not enclosed in braces.
The assembly code should like:
  "evex vcvtps2pd xmm0, xmm1"

Differential Revision: https://reviews.llvm.org/D90441
This commit is contained in:
Liu, Chen3 2020-10-30 11:11:35 +08:00
parent 9a99d23a1b
commit 776f92e067
3 changed files with 63 additions and 4 deletions

View File

@ -791,7 +791,27 @@ std::string GCCAsmStmt::generateAsmString(const ASTContext &C) const {
/// Assemble final IR asm string (MS-style).
std::string MSAsmStmt::generateAsmString(const ASTContext &C) const {
// FIXME: This needs to be translated into the IR string representation.
return std::string(AsmStr);
SmallVector<StringRef, 8> Pieces;
AsmStr.split(Pieces, "\n\t");
std::string MSAsmString;
for (size_t I = 0, E = Pieces.size(); I < E; ++I) {
StringRef Instruction = Pieces[I];
// For vex/vex2/vex3/evex masm style prefix, convert it to att style
// since we don't support masm style prefix in backend.
if (Instruction.startswith("vex "))
MSAsmString += '{' + Instruction.substr(0, 3).str() + '}' +
Instruction.substr(3).str();
else if (Instruction.startswith("vex2 ") ||
Instruction.startswith("vex3 ") || Instruction.startswith("evex "))
MSAsmString += '{' + Instruction.substr(0, 4).str() + '}' +
Instruction.substr(4).str();
else
MSAsmString += Instruction.str();
// If this is not the last instruction, adding back the '\n\t'.
if (I < E - 1)
MSAsmString += "\n\t";
}
return MSAsmString;
}
Expr *MSAsmStmt::getOutputExpr(unsigned i) {

View File

@ -0,0 +1,14 @@
// REQUIRES: x86-registered-target
// RUN:%clang_cc1 %s -ferror-limit 0 -triple=x86_64-pc-windows-msvc -target-feature +avx512f -target-feature +avx2 -target-feature +avx512vl -fasm-blocks -mllvm -x86-asm-syntax=intel -S -emit-llvm -o - | FileCheck %s -check-prefix=INTEL
// RUN:%clang_cc1 %s -ferror-limit 0 -triple=x86_64-pc-windows-msvc -target-feature +avx512f -target-feature +avx2 -target-feature +avx512vl -fasm-blocks -mllvm -x86-asm-syntax=att -S -emit-llvm -o - | FileCheck %s -check-prefix=ATT
void check_inline_prefix(void) {
__asm {
// INTEL: call void asm sideeffect inteldialect "{vex} vcvtps2pd xmm0, xmm1\0A\09{vex2} vcvtps2pd xmm0, xmm1\0A\09{vex3} vcvtps2pd xmm0, xmm1\0A\09{evex} vcvtps2pd xmm0, xmm1", "~{xmm0},~{dirflag},~{fpsr},~{flags}"()
// ATT: call void asm sideeffect inteldialect "{vex} vcvtps2pd xmm0, xmm1\0A\09{vex2} vcvtps2pd xmm0, xmm1\0A\09{vex3} vcvtps2pd xmm0, xmm1\0A\09{evex} vcvtps2pd xmm0, xmm1", "~{xmm0},~{dirflag},~{fpsr},~{flags}"()
vex vcvtps2pd xmm0, xmm1
vex2 vcvtps2pd xmm0, xmm1
vex3 vcvtps2pd xmm0, xmm1
evex vcvtps2pd xmm0, xmm1
}
}

View File

@ -3064,7 +3064,26 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
}
continue;
}
// Parse MASM style pseudo prefixes.
if (isParsingMSInlineAsm()) {
if (Name.equals_lower("vex"))
ForcedVEXEncoding = VEXEncoding_VEX;
else if (Name.equals_lower("vex2"))
ForcedVEXEncoding = VEXEncoding_VEX2;
else if (Name.equals_lower("vex3"))
ForcedVEXEncoding = VEXEncoding_VEX3;
else if (Name.equals_lower("evex"))
ForcedVEXEncoding = VEXEncoding_EVEX;
if (ForcedVEXEncoding != VEXEncoding_Default) {
if (getLexer().isNot(AsmToken::Identifier))
return Error(Parser.getTok().getLoc(), "Expected identifier");
// FIXME: The mnemonic won't match correctly if its not in lower case.
Name = Parser.getTok().getString();
NameLoc = Parser.getTok().getLoc();
Parser.Lex();
}
}
break;
}
@ -4370,10 +4389,16 @@ bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
MCInst Inst;
// If VEX3 encoding is forced, we need to pass the USE_VEX3 flag to the
// encoder.
if (ForcedVEXEncoding == VEXEncoding_VEX3)
// If VEX/EVEX encoding is forced, we need to pass the USE_* flag to the
// encoder and printer.
if (ForcedVEXEncoding == VEXEncoding_VEX)
Prefixes |= X86::IP_USE_VEX;
else if (ForcedVEXEncoding == VEXEncoding_VEX2)
Prefixes |= X86::IP_USE_VEX2;
else if (ForcedVEXEncoding == VEXEncoding_VEX3)
Prefixes |= X86::IP_USE_VEX3;
else if (ForcedVEXEncoding == VEXEncoding_EVEX)
Prefixes |= X86::IP_USE_EVEX;
// Set encoded flags for {disp8} and {disp32}.
if (ForcedDispEncoding == DispEncoding_Disp8)