Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 7cc97eb

Browse files
committed
Extract global_asm module
1 parent c5adc96 commit 7cc97eb

File tree

3 files changed

+119
-107
lines changed

3 files changed

+119
-107
lines changed

src/driver/aot.rs

Lines changed: 2 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
//! The AOT driver uses [`cranelift_object`] to write object files suitable for linking into a
22
//! standalone executable.
33
4-
use std::path::PathBuf;
5-
6-
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
74
use rustc_codegen_ssa::back::metadata::create_compressed_metadata_file;
85
use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, ModuleKind};
96
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@@ -175,23 +172,7 @@ fn module_codegen(
175172
}
176173
MonoItem::Static(def_id) => crate::constant::codegen_static(tcx, &mut module, def_id),
177174
MonoItem::GlobalAsm(item_id) => {
178-
let item = cx.tcx.hir().item(item_id);
179-
if let rustc_hir::ItemKind::GlobalAsm(asm) = item.kind {
180-
if !asm.options.contains(InlineAsmOptions::ATT_SYNTAX) {
181-
cx.global_asm.push_str("\n.intel_syntax noprefix\n");
182-
} else {
183-
cx.global_asm.push_str("\n.att_syntax\n");
184-
}
185-
for piece in asm.template {
186-
match *piece {
187-
InlineAsmTemplatePiece::String(ref s) => cx.global_asm.push_str(s),
188-
InlineAsmTemplatePiece::Placeholder { .. } => todo!(),
189-
}
190-
}
191-
cx.global_asm.push_str("\n.att_syntax\n\n");
192-
} else {
193-
bug!("Expected GlobalAsm found {:?}", item);
194-
}
175+
crate::global_asm::codegen_global_asm_item(tcx, &mut cx.global_asm, item_id);
195176
}
196177
}
197178
}
@@ -217,7 +198,7 @@ fn module_codegen(
217198
)
218199
});
219200

220-
codegen_global_asm(tcx, cgu.name().as_str(), &cx.global_asm);
201+
crate::global_asm::compile_global_asm(tcx, cgu.name().as_str(), &cx.global_asm);
221202

222203
codegen_result
223204
}
@@ -353,92 +334,6 @@ pub(crate) fn run_aot(
353334
})
354335
}
355336

356-
fn codegen_global_asm(tcx: TyCtxt<'_>, cgu_name: &str, global_asm: &str) {
357-
use std::io::Write;
358-
use std::process::{Command, Stdio};
359-
360-
if global_asm.is_empty() {
361-
return;
362-
}
363-
364-
if cfg!(not(feature = "inline_asm"))
365-
|| tcx.sess.target.is_like_osx
366-
|| tcx.sess.target.is_like_windows
367-
{
368-
if global_asm.contains("__rust_probestack") {
369-
return;
370-
}
371-
372-
// FIXME fix linker error on macOS
373-
if cfg!(not(feature = "inline_asm")) {
374-
tcx.sess.fatal(
375-
"asm! and global_asm! support is disabled while compiling rustc_codegen_cranelift",
376-
);
377-
} else {
378-
tcx.sess.fatal("asm! and global_asm! are not yet supported on macOS and Windows");
379-
}
380-
}
381-
382-
let assembler = crate::toolchain::get_toolchain_binary(tcx.sess, "as");
383-
let linker = crate::toolchain::get_toolchain_binary(tcx.sess, "ld");
384-
385-
// Remove all LLVM style comments
386-
let global_asm = global_asm
387-
.lines()
388-
.map(|line| if let Some(index) = line.find("//") { &line[0..index] } else { line })
389-
.collect::<Vec<_>>()
390-
.join("\n");
391-
392-
let output_object_file = tcx.output_filenames(()).temp_path(OutputType::Object, Some(cgu_name));
393-
394-
// Assemble `global_asm`
395-
let global_asm_object_file = add_file_stem_postfix(output_object_file.clone(), ".asm");
396-
let mut child = Command::new(assembler)
397-
.arg("-o")
398-
.arg(&global_asm_object_file)
399-
.stdin(Stdio::piped())
400-
.spawn()
401-
.expect("Failed to spawn `as`.");
402-
child.stdin.take().unwrap().write_all(global_asm.as_bytes()).unwrap();
403-
let status = child.wait().expect("Failed to wait for `as`.");
404-
if !status.success() {
405-
tcx.sess.fatal(&format!("Failed to assemble `{}`", global_asm));
406-
}
407-
408-
// Link the global asm and main object file together
409-
let main_object_file = add_file_stem_postfix(output_object_file.clone(), ".main");
410-
std::fs::rename(&output_object_file, &main_object_file).unwrap();
411-
let status = Command::new(linker)
412-
.arg("-r") // Create a new object file
413-
.arg("-o")
414-
.arg(output_object_file)
415-
.arg(&main_object_file)
416-
.arg(&global_asm_object_file)
417-
.status()
418-
.unwrap();
419-
if !status.success() {
420-
tcx.sess.fatal(&format!(
421-
"Failed to link `{}` and `{}` together",
422-
main_object_file.display(),
423-
global_asm_object_file.display(),
424-
));
425-
}
426-
427-
std::fs::remove_file(global_asm_object_file).unwrap();
428-
std::fs::remove_file(main_object_file).unwrap();
429-
}
430-
431-
fn add_file_stem_postfix(mut path: PathBuf, postfix: &str) -> PathBuf {
432-
let mut new_filename = path.file_stem().unwrap().to_owned();
433-
new_filename.push(postfix);
434-
if let Some(extension) = path.extension() {
435-
new_filename.push(".");
436-
new_filename.push(extension);
437-
}
438-
path.set_file_name(new_filename);
439-
path
440-
}
441-
442337
// Adapted from https://github.com/rust-lang/rust/blob/303d8aff6092709edd4dbd35b1c88e9aa40bf6d8/src/librustc_codegen_ssa/base.rs#L922-L953
443338
fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> CguReuse {
444339
if !tcx.dep_graph.is_fully_enabled() {

src/global_asm.rs

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
//! The AOT driver uses [`cranelift_object`] to write object files suitable for linking into a
2+
//! standalone executable.
3+
4+
use std::path::PathBuf;
5+
6+
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
7+
use rustc_hir::ItemId;
8+
use rustc_session::config::OutputType;
9+
10+
use crate::prelude::*;
11+
12+
pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String, item_id: ItemId) {
13+
let item = tcx.hir().item(item_id);
14+
if let rustc_hir::ItemKind::GlobalAsm(asm) = item.kind {
15+
if !asm.options.contains(InlineAsmOptions::ATT_SYNTAX) {
16+
global_asm.push_str("\n.intel_syntax noprefix\n");
17+
} else {
18+
global_asm.push_str("\n.att_syntax\n");
19+
}
20+
for piece in asm.template {
21+
match *piece {
22+
InlineAsmTemplatePiece::String(ref s) => global_asm.push_str(s),
23+
InlineAsmTemplatePiece::Placeholder { .. } => todo!(),
24+
}
25+
}
26+
global_asm.push_str("\n.att_syntax\n\n");
27+
} else {
28+
bug!("Expected GlobalAsm found {:?}", item);
29+
}
30+
}
31+
32+
pub(crate) fn compile_global_asm(tcx: TyCtxt<'_>, cgu_name: &str, global_asm: &str) {
33+
use std::io::Write;
34+
use std::process::{Command, Stdio};
35+
36+
if global_asm.is_empty() {
37+
return;
38+
}
39+
40+
if cfg!(not(feature = "inline_asm"))
41+
|| tcx.sess.target.is_like_osx
42+
|| tcx.sess.target.is_like_windows
43+
{
44+
if global_asm.contains("__rust_probestack") {
45+
return;
46+
}
47+
48+
// FIXME fix linker error on macOS
49+
if cfg!(not(feature = "inline_asm")) {
50+
tcx.sess.fatal(
51+
"asm! and global_asm! support is disabled while compiling rustc_codegen_cranelift",
52+
);
53+
} else {
54+
tcx.sess.fatal("asm! and global_asm! are not yet supported on macOS and Windows");
55+
}
56+
}
57+
58+
let assembler = crate::toolchain::get_toolchain_binary(tcx.sess, "as");
59+
let linker = crate::toolchain::get_toolchain_binary(tcx.sess, "ld");
60+
61+
// Remove all LLVM style comments
62+
let global_asm = global_asm
63+
.lines()
64+
.map(|line| if let Some(index) = line.find("//") { &line[0..index] } else { line })
65+
.collect::<Vec<_>>()
66+
.join("\n");
67+
68+
let output_object_file = tcx.output_filenames(()).temp_path(OutputType::Object, Some(cgu_name));
69+
70+
// Assemble `global_asm`
71+
let global_asm_object_file = add_file_stem_postfix(output_object_file.clone(), ".asm");
72+
let mut child = Command::new(assembler)
73+
.arg("-o")
74+
.arg(&global_asm_object_file)
75+
.stdin(Stdio::piped())
76+
.spawn()
77+
.expect("Failed to spawn `as`.");
78+
child.stdin.take().unwrap().write_all(global_asm.as_bytes()).unwrap();
79+
let status = child.wait().expect("Failed to wait for `as`.");
80+
if !status.success() {
81+
tcx.sess.fatal(&format!("Failed to assemble `{}`", global_asm));
82+
}
83+
84+
// Link the global asm and main object file together
85+
let main_object_file = add_file_stem_postfix(output_object_file.clone(), ".main");
86+
std::fs::rename(&output_object_file, &main_object_file).unwrap();
87+
let status = Command::new(linker)
88+
.arg("-r") // Create a new object file
89+
.arg("-o")
90+
.arg(output_object_file)
91+
.arg(&main_object_file)
92+
.arg(&global_asm_object_file)
93+
.status()
94+
.unwrap();
95+
if !status.success() {
96+
tcx.sess.fatal(&format!(
97+
"Failed to link `{}` and `{}` together",
98+
main_object_file.display(),
99+
global_asm_object_file.display(),
100+
));
101+
}
102+
103+
std::fs::remove_file(global_asm_object_file).unwrap();
104+
std::fs::remove_file(main_object_file).unwrap();
105+
}
106+
107+
fn add_file_stem_postfix(mut path: PathBuf, postfix: &str) -> PathBuf {
108+
let mut new_filename = path.file_stem().unwrap().to_owned();
109+
new_filename.push(postfix);
110+
if let Some(extension) = path.extension() {
111+
new_filename.push(".");
112+
new_filename.push(extension);
113+
}
114+
path.set_file_name(new_filename);
115+
path
116+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ mod constant;
5656
mod debuginfo;
5757
mod discriminant;
5858
mod driver;
59+
mod global_asm;
5960
mod inline_asm;
6061
mod intrinsics;
6162
mod linkage;

0 commit comments

Comments
 (0)