diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp --- a/clang/lib/AST/Stmt.cpp +++ b/clang/lib/AST/Stmt.cpp @@ -791,7 +791,27 @@ /// 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 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) { diff --git a/clang/test/CodeGen/X86/ms-inline-asm-prefix.c b/clang/test/CodeGen/X86/ms-inline-asm-prefix.c new file mode 100644 --- /dev/null +++ b/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 + } +} diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -3064,7 +3064,26 @@ } 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 @@ 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)