Skip to content

Commit 2e24cdb

Browse files
committed
squashed changes:
- codegen tests: change `windows` to `win` - cleanup - fix review comments - better way of checking for thumb - get the mangled name from the codegen backend - propagate function alignment - fix gcc backend - fix asan test - check that assembler mode restored
1 parent 589ebb8 commit 2e24cdb

File tree

9 files changed

+101
-67
lines changed

9 files changed

+101
-67
lines changed

compiler/rustc_codegen_gcc/src/asm.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,13 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
865865
template_str.push_str("\n.popsection");
866866
self.context.add_top_level_asm(None, &template_str);
867867
}
868+
869+
fn mangled_name(&self, instance: Instance<'tcx>) -> String {
870+
// TODO(@Amanieu): Additional mangling is needed on
871+
// some targets to add a leading underscore (Mach-O)
872+
// or byte count suffixes (x86 Windows).
873+
self.tcx.symbol_name(instance).name.to_string()
874+
}
868875
}
869876

870877
fn modifier_to_gcc(

compiler/rustc_codegen_llvm/src/asm.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,14 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
442442
);
443443
}
444444
}
445+
446+
fn mangled_name(&self, instance: Instance<'tcx>) -> String {
447+
let llval = self.get_fn(instance);
448+
llvm::build_string(|s| unsafe {
449+
llvm::LLVMRustGetMangledName(llval, s);
450+
})
451+
.expect("symbol is not valid UTF-8")
452+
}
445453
}
446454

447455
pub(crate) fn inline_asm_call<'ll>(

compiler/rustc_codegen_ssa/src/mir/naked_asm.rs

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_middle::mir::{Body, InlineAsmOperand};
44
use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf};
55
use rustc_middle::ty::{Instance, TyCtxt};
66
use rustc_middle::{bug, ty};
7-
use rustc_target::asm::InlineAsmArch;
7+
use rustc_span::sym;
88

99
use crate::common;
1010
use crate::traits::{AsmCodegenMethods, BuilderMethods, GlobalAsmOperandRef, MiscCodegenMethods};
@@ -31,7 +31,8 @@ pub(crate) fn codegen_naked_asm<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
3131
operands.iter().map(|op| inline_to_global_operand::<Bx>(cx, instance, op)).collect();
3232

3333
let item_data = cx.codegen_unit().items().get(&MonoItem::Fn(instance)).unwrap();
34-
let (begin, end) = crate::mir::naked_asm::prefix_and_suffix(cx.tcx(), instance, item_data);
34+
let name = cx.mangled_name(instance);
35+
let (begin, end) = prefix_and_suffix(cx.tcx(), instance, &name, item_data);
3536

3637
let mut template_vec = Vec::new();
3738
template_vec.push(rustc_ast::ast::InlineAsmTemplatePiece::String(begin.into()));
@@ -108,7 +109,7 @@ impl AsmBinaryFormat {
108109
fn from_target(target: &rustc_target::spec::Target) -> Self {
109110
if target.is_like_windows {
110111
Self::Coff
111-
} else if target.options.vendor == "apple" {
112+
} else if target.is_like_osx {
112113
Self::Macho
113114
} else {
114115
Self::Elf
@@ -119,33 +120,29 @@ impl AsmBinaryFormat {
119120
fn prefix_and_suffix<'tcx>(
120121
tcx: TyCtxt<'tcx>,
121122
instance: Instance<'tcx>,
123+
asm_name: &str,
122124
item_data: &MonoItemData,
123125
) -> (String, String) {
124126
use std::fmt::Write;
125127

126-
let target = &tcx.sess.target;
127-
let target_arch = tcx.sess.asm_arch;
128-
129-
let is_arm = target.arch == "arm";
130-
let is_thumb = is_arm && target.llvm_target.contains("thumb");
131-
132-
let mangle = (target.is_like_windows && matches!(target_arch, Some(InlineAsmArch::X86)))
133-
|| target.options.vendor == "apple";
134-
135-
let asm_name = format!("{}{}", if mangle { "_" } else { "" }, tcx.symbol_name(instance).name);
128+
let is_arm = tcx.sess.target.arch == "arm";
129+
let is_thumb = tcx.sess.unstable_target_features.contains(&sym::thumb_mode);
136130

137131
let attrs = tcx.codegen_fn_attrs(instance.def_id());
138132
let link_section = attrs.link_section.map(|symbol| symbol.as_str().to_string());
133+
let align = attrs.alignment.map(|a| a.bytes()).unwrap_or(4);
139134

135+
// See https://sourceware.org/binutils/docs/as/ARM-Directives.html for info on these directives.
136+
// In particular, `.arm` can also be written `.code 32` and `.thumb` as `.code 16`.
140137
let (arch_prefix, arch_suffix) = if is_arm {
141138
(
142139
match attrs.instruction_set {
143140
None => match is_thumb {
144141
true => ".thumb\n.thumb_func",
145142
false => ".arm",
146143
},
147-
Some(InstructionSetAttr::ArmA32) => ".arm",
148144
Some(InstructionSetAttr::ArmT32) => ".thumb\n.thumb_func",
145+
Some(InstructionSetAttr::ArmA32) => ".arm",
149146
},
150147
match is_thumb {
151148
true => ".thumb",
@@ -173,7 +170,7 @@ fn prefix_and_suffix<'tcx>(
173170
};
174171

175172
writeln!(begin, ".pushsection {section},\"ax\", {progbits}").unwrap();
176-
writeln!(begin, ".balign 4").unwrap();
173+
writeln!(begin, ".balign {align}").unwrap();
177174
writeln!(begin, ".globl {asm_name}").unwrap();
178175
if let Visibility::Hidden = item_data.visibility {
179176
writeln!(begin, ".hidden {asm_name}").unwrap();
@@ -194,7 +191,7 @@ fn prefix_and_suffix<'tcx>(
194191
AsmBinaryFormat::Macho => {
195192
let section = link_section.unwrap_or("__TEXT,__text".to_string());
196193
writeln!(begin, ".pushsection {},regular,pure_instructions", section).unwrap();
197-
writeln!(begin, ".balign 4").unwrap();
194+
writeln!(begin, ".balign {align}").unwrap();
198195
writeln!(begin, ".globl {asm_name}").unwrap();
199196
if let Visibility::Hidden = item_data.visibility {
200197
writeln!(begin, ".private_extern {asm_name}").unwrap();
@@ -210,7 +207,7 @@ fn prefix_and_suffix<'tcx>(
210207
AsmBinaryFormat::Coff => {
211208
let section = link_section.unwrap_or(format!(".text.{asm_name}"));
212209
writeln!(begin, ".pushsection {},\"xr\"", section).unwrap();
213-
writeln!(begin, ".balign 4").unwrap();
210+
writeln!(begin, ".balign {align}").unwrap();
214211
writeln!(begin, ".globl {asm_name}").unwrap();
215212
writeln!(begin, ".def {asm_name}").unwrap();
216213
writeln!(begin, ".scl 2").unwrap();

compiler/rustc_codegen_ssa/src/traits/asm.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,11 @@ pub trait AsmCodegenMethods<'tcx> {
6868
options: InlineAsmOptions,
6969
line_spans: &[Span],
7070
);
71+
72+
/// The mangled name of this instance
73+
///
74+
/// Additional mangling is used on
75+
/// some targets to add a leading underscore (Mach-O)
76+
/// or byte count suffixes (x86 Windows).
77+
fn mangled_name(&self, instance: Instance<'tcx>) -> String;
7178
}

tests/codegen/naked-asan.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88
#![no_std]
99
#![feature(abi_x86_interrupt, naked_functions)]
1010

11-
// CHECK: define x86_intrcc void @page_fault_handler(ptr {{.*}}%0, i64 {{.*}}%1){{.*}}#[[ATTRS:[0-9]+]] {
11+
pub fn caller() {
12+
page_fault_handler(1, 2);
13+
}
14+
15+
// CHECK: declare x86_intrcc void @page_fault_handler(ptr {{.*}}, i64 {{.*}}){{.*}}#[[ATTRS:[0-9]+]]
1216
// CHECK-NOT: memcpy
1317
#[naked]
1418
#[no_mangle]

tests/codegen/naked-fn/aligned.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,12 @@
66
#![feature(naked_functions, fn_align)]
77
use std::arch::naked_asm;
88

9-
// CHECK: Function Attrs: naked
10-
// CHECK-NEXT: define{{.*}}void @naked_empty()
11-
// CHECK: align 16
9+
// CHECK: .balign 16
10+
// CHECK-LABEL: naked_empty:
1211
#[repr(align(16))]
1312
#[no_mangle]
1413
#[naked]
1514
pub unsafe extern "C" fn naked_empty() {
16-
// CHECK-NEXT: start:
17-
// CHECK-NEXT: call void asm
18-
// CHECK-NEXT: unreachable
15+
// CHECK: ret
1916
naked_asm!("ret");
2017
}

tests/codegen/naked-fn/generics.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#![crate_type = "lib"]
55
#![feature(naked_functions, asm_const)]
66

7-
use std::arch::asm;
7+
use std::arch::naked_asm;
88

99
#[no_mangle]
1010
fn test(x: u64) {
@@ -33,15 +33,14 @@ pub extern "C" fn using_const_generics<const N: u64>(x: u64) -> u64 {
3333
const M: u64 = 42;
3434

3535
unsafe {
36-
asm!(
36+
naked_asm!(
3737
"xor rax, rax",
3838
"add rax, rdi",
3939
"add rax, {}",
4040
"add rax, {}",
4141
"ret",
4242
const N,
4343
const M,
44-
options(noreturn),
4544
)
4645
}
4746
}
@@ -64,11 +63,10 @@ impl Invert for i64 {
6463
#[naked]
6564
pub extern "C" fn generic_function<T: Invert>(x: i64) -> i64 {
6665
unsafe {
67-
asm!(
66+
naked_asm!(
6867
"call {}",
6968
"ret",
7069
sym <T as Invert>::invert,
71-
options(noreturn),
7270
)
7371
}
7472
}
@@ -85,7 +83,7 @@ impl Foo {
8583
#[naked]
8684
#[no_mangle]
8785
extern "C" fn method(self) -> u64 {
88-
unsafe { asm!("mov rax, rdi", "ret", options(noreturn)) }
86+
unsafe { naked_asm!("mov rax, rdi", "ret") }
8987
}
9088
}
9189

@@ -101,7 +99,7 @@ impl Bar for Foo {
10199
#[naked]
102100
#[no_mangle]
103101
extern "C" fn trait_method(self) -> u64 {
104-
unsafe { asm!("mov rax, rdi", "ret", options(noreturn)) }
102+
unsafe { naked_asm!("mov rax, rdi", "ret") }
105103
}
106104
}
107105

@@ -113,5 +111,5 @@ impl Bar for Foo {
113111
#[naked]
114112
#[no_mangle]
115113
pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize {
116-
asm!("lea rax, [rdi + rsi]", "ret", options(noreturn));
114+
naked_asm!("lea rax, [rdi + rsi]", "ret");
117115
}
Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
//@ compile-flags: --target armv5te-none-eabi
2-
//@ needs-llvm-components: arm
1+
//@ revisions: arm-mode thumb-mode
2+
//@ [arm-mode] compile-flags: --target armv5te-none-eabi
3+
//@ [thumb-mode] compile-flags: --target thumbv5te-none-eabi
4+
//@ [arm-mode] needs-llvm-components: arm
5+
//@ [thumb-mode] needs-llvm-components: arm
36

47
#![crate_type = "lib"]
58
#![feature(no_core, lang_items, rustc_attrs, naked_functions)]
69
#![no_core]
710

811
#[rustc_builtin_macro]
9-
macro_rules! asm {
12+
macro_rules! naked_asm {
1013
() => {};
1114
}
1215

@@ -15,29 +18,42 @@ trait Sized {}
1518
#[lang = "copy"]
1619
trait Copy {}
1720

21+
// arm-mode: .arm
22+
// thumb-mode: .thumb
1823
// CHECK-LABEL: test_unspecified:
19-
// CHECK: .arm
24+
// CHECK: bx lr
25+
// CHECK: .popsection
26+
// arm-mode: .arm
27+
// thumb-mode: .thumb
2028
#[no_mangle]
2129
#[naked]
2230
unsafe extern "C" fn test_unspecified() {
23-
asm!("bx lr", options(noreturn));
31+
naked_asm!("bx lr");
2432
}
2533

26-
// CHECK-LABEL: test_thumb:
2734
// CHECK: .thumb
2835
// CHECK: .thumb_func
36+
// CHECK-LABEL: test_thumb:
37+
// CHECK: bx lr
38+
// CHECK: .popsection
39+
// arm-mode: .arm
40+
// thumb-mode: .thumb
2941
#[no_mangle]
3042
#[naked]
3143
#[instruction_set(arm::t32)]
3244
unsafe extern "C" fn test_thumb() {
33-
asm!("bx lr", options(noreturn));
45+
naked_asm!("bx lr");
3446
}
3547

36-
// CHECK-LABEL: test_arm:
3748
// CHECK: .arm
49+
// CHECK-LABEL: test_arm:
50+
// CHECK: bx lr
51+
// CHECK: .popsection
52+
// arm-mode: .arm
53+
// thumb-mode: .thumb
3854
#[no_mangle]
3955
#[naked]
40-
#[instruction_set(arm::t32)]
56+
#[instruction_set(arm::a32)]
4157
unsafe extern "C" fn test_arm() {
42-
asm!("bx lr", options(noreturn));
58+
naked_asm!("bx lr");
4359
}

0 commit comments

Comments
 (0)