thakis created this revision. thakis added a reviewer: hans. Herald added subscribers: dexonsmith, dang. thakis requested review of this revision.
With this, void f() { __asm__("mov eax, ebx"); } now compiles with clang with -masm=intel. This matches gcc. The flag is not accepted in clang-cl mode. It has no effect on MSVC-style `__asm {}` blocks, which are unconditionally in intel mode both before and after this change. On difference to gcc is that in clang, inline asm strings are "local" while they're "global" in gcc. Building the following with -masm=intel works with clang, but not with gcc where the ".att_syntax" from the 2nd __asm__() is in effect until file end (or until a ".intel_syntax" somewhere later in the file): __asm__("mov eax, ebx"); __asm__(".att_syntax\nmovl %ebx, %eax"); __asm__("mov eax, ebx"); Related to PR21401. https://reviews.llvm.org/D113707 Files: clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Basic/CodeGenOptions.h clang/include/clang/Driver/Options.td clang/lib/CodeGen/CGStmt.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/CodeGen/inline-asm-intel.c clang/test/Driver/masm.c
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; } 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/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/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/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<MSAsmStmt>(&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/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<mwatchos_simulator_version_min_EQ>; def march_EQ : Joined<["-"], "march=">, Group<m_Group>, Flags<[CoreOption]>; def masm_EQ : Joined<["-"], "masm=">, Group<m_Group>, Flags<[NoXarchOption]>; +def inline_asm_EQ : Joined<["-"], "inline-asm=">, Group<m_Group>, Flags<[CC1Option]>; def mcmodel_EQ : Joined<["-"], "mcmodel=">, Group<m_Group>, Flags<[CC1Option]>, MarshallingInfoString<TargetOpts<"CodeModel">, [{"default"}]>; def mtls_size_EQ : Joined<["-"], "mtls-size=">, Group<m_Group>, Flags<[NoXarchOption, CC1Option]>, 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=<file>", "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.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits