Skip to content

Commit

Permalink
[X86] Add support for vex, vex2, vex3, and evex for MASM
Browse files Browse the repository at this point in the history
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
  • Loading branch information
MoringLiu committed Nov 20, 2020
1 parent 9a99d23 commit 776f92e
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 4 deletions.
22 changes: 21 additions & 1 deletion clang/lib/AST/Stmt.cpp
Expand Up @@ -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) {
Expand Down
14 changes: 14 additions & 0 deletions clang/test/CodeGen/X86/ms-inline-asm-prefix.c
@@ -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
}
}
31 changes: 28 additions & 3 deletions llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 776f92e

Please sign in to comment.