Skip to content

Commit a6a2477

Browse files
author
Jorge Aparicio
committed
use write::run_assembler
1 parent fcde990 commit a6a2477

File tree

3 files changed

+26
-83
lines changed

3 files changed

+26
-83
lines changed

src/librustc_back/target/mod.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -359,9 +359,10 @@ pub struct TargetOptions {
359359
// will 'just work'.
360360
pub obj_is_bitcode: bool,
361361

362-
// LLVM can't produce object files for MSP430. Instead, we'll make LLVM emit
363-
// assembly and then use `msp430-as` to turn that assembly into an object file
364-
pub obj_needs_as: bool,
362+
// LLVM can't produce object files for this target. Instead, we'll make LLVM
363+
// emit assembly and then use `gcc` to turn that assembly into an object
364+
// file
365+
pub no_integrated_as: bool,
365366

366367
/// Don't use this field; instead use the `.max_atomic_width()` method.
367368
pub max_atomic_width: Option<u64>,
@@ -420,7 +421,7 @@ impl Default for TargetOptions {
420421
allow_asm: true,
421422
has_elf_tls: false,
422423
obj_is_bitcode: false,
423-
obj_needs_as: false,
424+
no_integrated_as: false,
424425
max_atomic_width: None,
425426
panic_strategy: PanicStrategy::Unwind,
426427
abi_blacklist: vec![],
@@ -581,7 +582,7 @@ impl Target {
581582
key!(exe_allocation_crate);
582583
key!(has_elf_tls, bool);
583584
key!(obj_is_bitcode, bool);
584-
key!(obj_needs_as, bool);
585+
key!(no_integrated_as, bool);
585586
key!(max_atomic_width, Option<u64>);
586587
try!(key!(panic_strategy, PanicStrategy));
587588

@@ -741,7 +742,7 @@ impl ToJson for Target {
741742
target_option_val!(exe_allocation_crate);
742743
target_option_val!(has_elf_tls);
743744
target_option_val!(obj_is_bitcode);
744-
target_option_val!(obj_needs_as);
745+
target_option_val!(no_integrated_as);
745746
target_option_val!(max_atomic_width);
746747
target_option_val!(panic_strategy);
747748

src/librustc_driver/driver.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -1056,14 +1056,25 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
10561056
pub fn phase_5_run_llvm_passes(sess: &Session,
10571057
trans: &trans::CrateTranslation,
10581058
outputs: &OutputFilenames) -> CompileResult {
1059-
if sess.opts.cg.no_integrated_as {
1059+
if sess.opts.cg.no_integrated_as || sess.target.target.options.no_integrated_as {
10601060
let output_types = OutputTypes::new(&[(OutputType::Assembly, None)]);
10611061
time(sess.time_passes(),
10621062
"LLVM passes",
10631063
|| write::run_passes(sess, trans, &output_types, outputs));
10641064

10651065
write::run_assembler(sess, outputs);
10661066

1067+
// HACK the linker expects the object file to be named foo.0.o but
1068+
// `run_assembler` produces an object named just foo.o. Rename it if we
1069+
// are going to build an executable
1070+
if sess.opts.output_types.contains_key(&OutputType::Exe) {
1071+
let f = outputs.path(OutputType::Object);
1072+
fs::copy(&f,
1073+
f.with_file_name(format!("{}.0.o",
1074+
f.file_stem().unwrap().to_string_lossy()))).unwrap();
1075+
fs::remove_file(f).unwrap();
1076+
}
1077+
10671078
// Remove assembly source, unless --save-temps was specified
10681079
if !sess.opts.cg.save_temps {
10691080
fs::remove_file(&outputs.temp_path(OutputType::Assembly, None)).unwrap();

src/librustc_trans/back/write.rs

+7-76
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,6 @@ use errors::emitter::Emitter;
2626
use syntax_pos::MultiSpan;
2727
use context::{is_pie_binary, get_reloc_model};
2828

29-
use std::ascii;
30-
use std::char;
31-
use std::process::Command;
3229
use std::ffi::{CStr, CString};
3330
use std::fs;
3431
use std::path::{Path, PathBuf};
@@ -265,9 +262,6 @@ pub struct ModuleConfig {
265262
// make the object file bitcode. Provides easy compatibility with
266263
// emscripten's ecc compiler, when used as the linker.
267264
obj_is_bitcode: bool,
268-
// LLVM can't produce object files for MSP430. Instead, we'll make LLVM emit
269-
// assembly and then use `msp430-as` to turn that assembly into an object file
270-
obj_needs_as: bool,
271265
}
272266

273267
unsafe impl Send for ModuleConfig { }
@@ -287,7 +281,6 @@ impl ModuleConfig {
287281
emit_asm: false,
288282
emit_obj: false,
289283
obj_is_bitcode: false,
290-
obj_needs_as: false,
291284

292285
no_verify: false,
293286
no_prepopulate_passes: false,
@@ -307,7 +300,6 @@ impl ModuleConfig {
307300
self.time_passes = sess.time_passes();
308301
self.inline_threshold = sess.opts.cg.inline_threshold;
309302
self.obj_is_bitcode = sess.target.target.options.obj_is_bitcode;
310-
self.obj_needs_as = sess.target.target.options.obj_needs_as;
311303

312304
// Copy what clang does by turning on loop vectorization at O2 and
313305
// slp vectorization at O3. Otherwise configure other optimization aspects
@@ -565,13 +557,10 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
565557
// machine code, instead copy the .o file from the .bc
566558
let write_bc = config.emit_bc || config.obj_is_bitcode;
567559
let rm_bc = !config.emit_bc && config.obj_is_bitcode;
568-
let write_asm = config.emit_asm || config.obj_needs_as;
569-
let rm_asm = !config.emit_obj && config.obj_needs_as;
570560
let write_obj = config.emit_obj && !config.obj_is_bitcode;
571561
let copy_bc_to_obj = config.emit_obj && config.obj_is_bitcode;
572562

573563
let bc_out = output_names.temp_path(OutputType::Bitcode, module_name);
574-
let asm_out = output_names.temp_path(OutputType::Assembly, module_name);
575564
let obj_out = output_names.temp_path(OutputType::Object, module_name);
576565

577566
if write_bc {
@@ -589,25 +578,27 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
589578
})
590579
}
591580

592-
if write_asm {
581+
if config.emit_asm {
582+
let path = output_names.temp_path(OutputType::Assembly, module_name);
583+
593584
// We can't use the same module for asm and binary output, because that triggers
594585
// various errors like invalid IR or broken binaries, so we might have to clone the
595586
// module to produce the asm output
596-
let llmod = if config.emit_obj && !config.obj_needs_as {
587+
let llmod = if config.emit_obj {
597588
llvm::LLVMCloneModule(llmod)
598589
} else {
599590
llmod
600591
};
601592
with_codegen(tm, llmod, config.no_builtins, |cpm| {
602-
write_output_file(cgcx.handler, tm, cpm, llmod, &asm_out,
593+
write_output_file(cgcx.handler, tm, cpm, llmod, &path,
603594
llvm::FileType::AssemblyFile);
604595
});
605-
if config.emit_obj && !config.obj_needs_as {
596+
if config.emit_obj {
606597
llvm::LLVMDisposeModule(llmod);
607598
}
608599
}
609600

610-
if write_obj && !config.obj_needs_as {
601+
if write_obj {
611602
with_codegen(tm, llmod, config.no_builtins, |cpm| {
612603
write_output_file(cgcx.handler, tm, cpm, llmod, &obj_out,
613604
llvm::FileType::ObjectFile);
@@ -622,73 +613,13 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
622613
}
623614
}
624615

625-
if config.obj_needs_as {
626-
// XXX most of the logic here has been copied from the link_natively
627-
// function (src/librustc_trans/back/link.rs)
628-
// TODO don't hardcode, maybe expose as a `as` field in the target
629-
// specification
630-
// TODO how to properly access `sess` here?
631-
let mut cmd = Command::new("msp430-as");
632-
cmd.arg("-o");
633-
cmd.arg(obj_out);
634-
cmd.arg(&asm_out);
635-
636-
info!("{:?}", &cmd);
637-
// let prog = time(sess.time_passes(), "running assembler",
638-
// || cmd.output());
639-
let prog = cmd.output();
640-
match prog {
641-
Ok(prog) => {
642-
fn escape_string(s: &[u8]) -> String {
643-
str::from_utf8(s).map(|s| s.to_owned())
644-
.unwrap_or_else(|_| {
645-
let mut x = "Non-UTF-8 output: ".to_string();
646-
x.extend(s.iter()
647-
.flat_map(|&b| ascii::escape_default(b))
648-
.map(|b| char::from_u32(b as u32).unwrap()));
649-
x
650-
})
651-
}
652-
if !prog.status.success() {
653-
let mut output = prog.stderr.clone();
654-
output.extend_from_slice(&prog.stdout);
655-
// sess.struct_err(&format!("assembling with `msp430-as` failed: {}",
656-
// prog.status))
657-
// .note(&format!("{:?}", &cmd))
658-
// .note(&escape_string(&output[..]))
659-
// .emit();
660-
// sess.abort_if_errors();
661-
}
662-
info!("linker stderr:\n{}", escape_string(&prog.stderr[..]));
663-
info!("linker stdout:\n{}", escape_string(&prog.stdout[..]));
664-
},
665-
Err(_) => {
666-
// sess.struct_err(&format!("could not exec the assembler `msp430-as`: {}", e))
667-
// .note(&format!("{:?}", &cmd))
668-
// .emit();
669-
// if e.kind() == io::ErrorKind::NotFound {
670-
// sess.note_without_error("MSP430 targets depend on the MSP430 assembler \
671-
// but `msp430-as` was not found");
672-
// }
673-
// sess.abort_if_errors();
674-
},
675-
}
676-
}
677-
678616
if rm_bc {
679617
debug!("removing_bitcode {:?}", bc_out);
680618
if let Err(e) = fs::remove_file(&bc_out) {
681619
cgcx.handler.err(&format!("failed to remove bitcode: {}", e));
682620
}
683621
}
684622

685-
if rm_asm {
686-
debug!("removing_assembly {:?}", bc_out);
687-
if let Err(e) = fs::remove_file(&asm_out) {
688-
cgcx.handler.err(&format!("failed to remove assembly: {}", e));
689-
}
690-
}
691-
692623
llvm::LLVMRustDisposeTargetMachine(tm);
693624
}
694625

0 commit comments

Comments
 (0)