Index: clang/include/clang/Basic/CodeGenOptions.h =================================================================== --- clang/include/clang/Basic/CodeGenOptions.h +++ clang/include/clang/Basic/CodeGenOptions.h @@ -97,6 +97,11 @@ Embed_Marker // Embed a marker as a placeholder for bitcode. }; + enum InlineAsmDialectKind { + IAD_ATT, + IAD_Intel, + }; + // This field stores one of the allowed values for the option // -fbasic-block-sections=. The allowed values with this option are: // {"labels", "all", "list=", "none"}. Index: clang/include/clang/Basic/CodeGenOptions.def =================================================================== --- clang/include/clang/Basic/CodeGenOptions.def +++ clang/include/clang/Basic/CodeGenOptions.def @@ -92,6 +92,8 @@ CODEGENOPT(ExplicitEmulatedTLS , 1, 0) ///< Set if -f[no-]emulated-tls is used. /// Embed Bitcode mode (off/all/bitcode/marker). ENUM_CODEGENOPT(EmbedBitcode, EmbedBitcodeKind, 2, Embed_Off) +/// Inline asm dialect, -masm=(att|intel) +ENUM_CODEGENOPT(InlineAsmDialect, InlineAsmDialectKind, 1, IAD_ATT) CODEGENOPT(ForbidGuardVariables , 1, 0) ///< Issue errors if C++ guard variables ///< are required. CODEGENOPT(FunctionSections , 1, 0) ///< Set when -ffunction-sections is enabled. Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -3131,6 +3131,7 @@ def mwatchsimulator_version_min_EQ : Joined<["-"], "mwatchsimulator-version-min=">, Alias; def march_EQ : Joined<["-"], "march=">, Group, Flags<[CoreOption]>; def masm_EQ : Joined<["-"], "masm=">, Group, Flags<[NoXarchOption]>; +def inline_asm_EQ : Joined<["-"], "inline-asm=">, Group, Flags<[CC1Option]>; def mcmodel_EQ : Joined<["-"], "mcmodel=">, Group, Flags<[CC1Option]>, MarshallingInfoString, [{"default"}]>; def mtls_size_EQ : Joined<["-"], "mtls-size=">, Group, Flags<[NoXarchOption, CC1Option]>, Index: clang/lib/CodeGen/CGStmt.cpp =================================================================== --- clang/lib/CodeGen/CGStmt.cpp +++ clang/lib/CodeGen/CGStmt.cpp @@ -2629,8 +2629,14 @@ llvm::FunctionType::get(ResultType, ArgTypes, false); bool HasSideEffect = S.isVolatile() || S.getNumOutputs() == 0; + + llvm::InlineAsm::AsmDialect GnuAsmDialect = + CGM.getCodeGenOpts().getInlineAsmDialect() == CodeGenOptions::IAD_ATT + ? llvm::InlineAsm::AD_ATT + : llvm::InlineAsm::AD_Intel; llvm::InlineAsm::AsmDialect AsmDialect = isa(&S) ? - llvm::InlineAsm::AD_Intel : llvm::InlineAsm::AD_ATT; + llvm::InlineAsm::AD_Intel : GnuAsmDialect; + llvm::InlineAsm *IA = llvm::InlineAsm::get( FTy, AsmString, Constraints, HasSideEffect, /* IsAlignStack */ false, AsmDialect, HasUnwindClobber); Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -2200,6 +2200,7 @@ if (Value == "intel" || Value == "att") { CmdArgs.push_back("-mllvm"); CmdArgs.push_back(Args.MakeArgString("-x86-asm-syntax=" + Value)); + CmdArgs.push_back(Args.MakeArgString("-inline-asm=" + Value)); } else { D.Diag(diag::err_drv_unsupported_option_argument) << A->getOption().getName() << Value; Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -1614,6 +1614,18 @@ } } + if (Arg *A = Args.getLastArg(options::OPT_inline_asm_EQ)) { + StringRef Value = A->getValue(); + if (Value == "att") { + Opts.InlineAsmDialect = CodeGenOptions::IAD_ATT; + } else if (Value == "intel") { + Opts.InlineAsmDialect = CodeGenOptions::IAD_Intel; + } else { + Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) + << A->getValue(); + } + } + // PIC defaults to -fno-direct-access-external-data while non-PIC defaults to // -fdirect-access-external-data. Opts.DirectAccessExternalData = Index: clang/test/CodeGen/inline-asm-intel.c =================================================================== --- /dev/null +++ clang/test/CodeGen/inline-asm-intel.c @@ -0,0 +1,14 @@ +// REQUIRES: x86-registered-target + +/// Accept intel inline asm but write it out as att: +// RUN: %clang_cc1 -triple i386-unknown-unknown -mllvm -x86-asm-syntax=att -inline-asm=intel -O0 -emit-llvm -S %s -o - | FileCheck --check-prefix=ATT %s + +/// Accept intel inline asm and write it out as intel: +// RUN: %clang_cc1 -triple i386-unknown-unknown -mllvm -x86-asm-syntax=intel -inline-asm=intel -O0 -emit-llvm -S %s -o - | FileCheck --check-prefix=INTEL %s + +void f() { + __asm__("mov eax, ebx"); + // ATT: movl %ebx, %eax + // INTEL: mov eax, ebx +} + Index: clang/test/Driver/masm.c =================================================================== --- clang/test/Driver/masm.c +++ clang/test/Driver/masm.c @@ -5,10 +5,11 @@ // RUN: %clang_cl --target=x86_64 /FA -### -- %s 2>&1 | FileCheck --check-prefix=CHECK-CL %s int f() { -// CHECK-INTEL: -x86-asm-syntax=intel -// CHECK-ATT: -x86-asm-syntax=att +// CHECK-INTEL: -x86-asm-syntax=intel -inline-asm=intel +// CHECK-ATT: -x86-asm-syntax=att -inline-asm=att // CHECK-SOMEREQUIRED: error: unsupported argument 'somerequired' to option 'masm=' // CHECK-ARM: warning: argument unused during compilation: '-masm=intel' // CHECK-CL: -x86-asm-syntax=intel +// CHECK-CL-NOT: -inline-asm=intel return 0; }