about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFolkert de Vries <folkert@folkertdev.nl>2025-07-07 19:23:06 +0200
committerFolkert de Vries <folkert@folkertdev.nl>2025-07-09 01:09:55 +0200
commit6fc5d4edda88d0dd28c45ccba1a1e217ddad11c4 (patch)
tree6894659a24c21ea01617122af9e8f7121cd35c96
parent1b0bc594a75dfc1cdedc6c17052cf44de101e632 (diff)
downloadrust-6fc5d4edda88d0dd28c45ccba1a1e217ddad11c4.tar.gz
rust-6fc5d4edda88d0dd28c45ccba1a1e217ddad11c4.zip
emit `.att_syntax` when global/naked asm use that option
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs22
-rw-r--r--tests/assembly/emit-intel-att-syntax.rs75
2 files changed, 90 insertions, 7 deletions
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index 9ddadcf16aa..a643a91141e 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -384,15 +384,19 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
     ) {
         let asm_arch = self.tcx.sess.asm_arch.unwrap();
 
-        // Default to Intel syntax on x86
-        let intel_syntax = matches!(asm_arch, InlineAsmArch::X86 | InlineAsmArch::X86_64)
-            && !options.contains(InlineAsmOptions::ATT_SYNTAX);
-
         // Build the template string
         let mut template_str = String::new();
-        if intel_syntax {
-            template_str.push_str(".intel_syntax\n");
+
+        // On X86 platforms there are two assembly syntaxes. Rust uses intel by default,
+        // but AT&T can be specified explicitly.
+        if matches!(asm_arch, InlineAsmArch::X86 | InlineAsmArch::X86_64) {
+            if options.contains(InlineAsmOptions::ATT_SYNTAX) {
+                template_str.push_str(".att_syntax\n")
+            } else {
+                template_str.push_str(".intel_syntax\n")
+            }
         }
+
         for piece in template {
             match *piece {
                 InlineAsmTemplatePiece::String(ref s) => template_str.push_str(s),
@@ -431,7 +435,11 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
                 }
             }
         }
-        if intel_syntax {
+
+        // Just to play it safe, if intel was used, reset the assembly syntax to att.
+        if matches!(asm_arch, InlineAsmArch::X86 | InlineAsmArch::X86_64)
+            && !options.contains(InlineAsmOptions::ATT_SYNTAX)
+        {
             template_str.push_str("\n.att_syntax\n");
         }
 
diff --git a/tests/assembly/emit-intel-att-syntax.rs b/tests/assembly/emit-intel-att-syntax.rs
new file mode 100644
index 00000000000..7b479a0f79e
--- /dev/null
+++ b/tests/assembly/emit-intel-att-syntax.rs
@@ -0,0 +1,75 @@
+//@ assembly-output: emit-asm
+//@ revisions: att intel
+//@ [att] compile-flags: -Cllvm-args=-x86-asm-syntax=att
+//@ [intel] compile-flags: -Cllvm-args=-x86-asm-syntax=intel
+//@ only-x86_64
+
+#![crate_type = "lib"]
+
+// CHECK-LABEL: naked_att:
+// intel-CHECK: mov rax, qword ptr [rdi]
+// intel-CHECK: ret
+// att-CHECK: movq (%rdi), %rax
+// att-CHECK: retq
+
+#[unsafe(naked)]
+#[unsafe(no_mangle)]
+extern "sysv64" fn naked_att() {
+    std::arch::naked_asm!(
+        "
+        movq (%rdi), %rax
+        retq
+        ",
+        options(att_syntax),
+    );
+}
+
+// CHECK-LABEL: naked_intel:
+// intel-CHECK: mov rax, rdi
+// intel-CHECK: ret
+// att-CHECK: movq (%rdi), %rax
+// att-CHECK: retq
+
+#[unsafe(naked)]
+#[unsafe(no_mangle)]
+extern "sysv64" fn naked_intel() {
+    std::arch::naked_asm!(
+        "
+        mov rax, rdi
+        ret
+        ",
+        options(),
+    );
+}
+
+// CHECK-LABEL: global_att:
+// intel-CHECK: mov rax, rdi
+// intel-CHECK: ret
+// att-CHECK: movq (%rdi), %rax
+// att-CHECK: retq
+
+core::arch::global_asm!(
+    "
+    .globl global_att
+    global_att:
+        movq (%rdi), %rax
+        retq
+    ",
+    options(att_syntax),
+);
+
+// CHECK-LABEL: global_intel:
+// intel-CHECK: mov rax, rdi
+// intel-CHECK: ret
+// att-CHECK: movq (%rdi), %rax
+// att-CHECK: retq
+
+core::arch::global_asm!(
+    "
+    .globl global_intel
+    global_intel:
+        mov rax, rdi
+        ret
+    ",
+    options(),
+);