about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJorge Aparicio <japaricious@gmail.com>2016-11-12 17:30:06 -0500
committerJorge Aparicio <japaricious@gmail.com>2016-11-12 17:45:15 -0500
commita6a247798619cf513fcab2421bade4dc99994e67 (patch)
tree882d6586b64244b2e865738d963a76fdf0ddf64e
parentfcde9904dbe7c4426a72b39a49b892eadb5a8940 (diff)
use write::run_assembler
-rw-r--r--src/librustc_back/target/mod.rs13
-rw-r--r--src/librustc_driver/driver.rs13
-rw-r--r--src/librustc_trans/back/write.rs83
3 files changed, 26 insertions, 83 deletions
diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs
index f6a0946dd5b..cc04582b19e 100644
--- a/src/librustc_back/target/mod.rs
+++ b/src/librustc_back/target/mod.rs
@@ -359,9 +359,10 @@ pub struct TargetOptions {
     // will 'just work'.
     pub obj_is_bitcode: bool,
 
-    // LLVM can't produce object files for MSP430. Instead, we'll make LLVM emit
-    // assembly and then use `msp430-as` to turn that assembly into an object file
-    pub obj_needs_as: bool,
+    // LLVM can't produce object files for this target. Instead, we'll make LLVM
+    // emit assembly and then use `gcc` to turn that assembly into an object
+    // file
+    pub no_integrated_as: bool,
 
     /// Don't use this field; instead use the `.max_atomic_width()` method.
     pub max_atomic_width: Option<u64>,
@@ -420,7 +421,7 @@ impl Default for TargetOptions {
             allow_asm: true,
             has_elf_tls: false,
             obj_is_bitcode: false,
-            obj_needs_as: false,
+            no_integrated_as: false,
             max_atomic_width: None,
             panic_strategy: PanicStrategy::Unwind,
             abi_blacklist: vec![],
@@ -581,7 +582,7 @@ impl Target {
         key!(exe_allocation_crate);
         key!(has_elf_tls, bool);
         key!(obj_is_bitcode, bool);
-        key!(obj_needs_as, bool);
+        key!(no_integrated_as, bool);
         key!(max_atomic_width, Option<u64>);
         try!(key!(panic_strategy, PanicStrategy));
 
@@ -741,7 +742,7 @@ impl ToJson for Target {
         target_option_val!(exe_allocation_crate);
         target_option_val!(has_elf_tls);
         target_option_val!(obj_is_bitcode);
-        target_option_val!(obj_needs_as);
+        target_option_val!(no_integrated_as);
         target_option_val!(max_atomic_width);
         target_option_val!(panic_strategy);
 
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index d8391849567..48bf490d685 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -1056,7 +1056,7 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 pub fn phase_5_run_llvm_passes(sess: &Session,
                                trans: &trans::CrateTranslation,
                                outputs: &OutputFilenames) -> CompileResult {
-    if sess.opts.cg.no_integrated_as {
+    if sess.opts.cg.no_integrated_as || sess.target.target.options.no_integrated_as {
         let output_types = OutputTypes::new(&[(OutputType::Assembly, None)]);
         time(sess.time_passes(),
              "LLVM passes",
@@ -1064,6 +1064,17 @@ pub fn phase_5_run_llvm_passes(sess: &Session,
 
         write::run_assembler(sess, outputs);
 
+        // HACK the linker expects the object file to be named foo.0.o but
+        // `run_assembler` produces an object named just foo.o. Rename it if we
+        // are going to build an executable
+        if sess.opts.output_types.contains_key(&OutputType::Exe) {
+            let f = outputs.path(OutputType::Object);
+            fs::copy(&f,
+                     f.with_file_name(format!("{}.0.o",
+                                              f.file_stem().unwrap().to_string_lossy()))).unwrap();
+            fs::remove_file(f).unwrap();
+        }
+
         // Remove assembly source, unless --save-temps was specified
         if !sess.opts.cg.save_temps {
             fs::remove_file(&outputs.temp_path(OutputType::Assembly, None)).unwrap();
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index 0af7c66ccd4..9012914deeb 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -26,9 +26,6 @@ use errors::emitter::Emitter;
 use syntax_pos::MultiSpan;
 use context::{is_pie_binary, get_reloc_model};
 
-use std::ascii;
-use std::char;
-use std::process::Command;
 use std::ffi::{CStr, CString};
 use std::fs;
 use std::path::{Path, PathBuf};
@@ -265,9 +262,6 @@ pub struct ModuleConfig {
     // make the object file bitcode. Provides easy compatibility with
     // emscripten's ecc compiler, when used as the linker.
     obj_is_bitcode: bool,
-    // LLVM can't produce object files for MSP430. Instead, we'll make LLVM emit
-    // assembly and then use `msp430-as` to turn that assembly into an object file
-    obj_needs_as: bool,
 }
 
 unsafe impl Send for ModuleConfig { }
@@ -287,7 +281,6 @@ impl ModuleConfig {
             emit_asm: false,
             emit_obj: false,
             obj_is_bitcode: false,
-            obj_needs_as: false,
 
             no_verify: false,
             no_prepopulate_passes: false,
@@ -307,7 +300,6 @@ impl ModuleConfig {
         self.time_passes = sess.time_passes();
         self.inline_threshold = sess.opts.cg.inline_threshold;
         self.obj_is_bitcode = sess.target.target.options.obj_is_bitcode;
-        self.obj_needs_as = sess.target.target.options.obj_needs_as;
 
         // Copy what clang does by turning on loop vectorization at O2 and
         // slp vectorization at O3. Otherwise configure other optimization aspects
@@ -565,13 +557,10 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
     // machine code, instead copy the .o file from the .bc
     let write_bc = config.emit_bc || config.obj_is_bitcode;
     let rm_bc = !config.emit_bc && config.obj_is_bitcode;
-    let write_asm = config.emit_asm || config.obj_needs_as;
-    let rm_asm = !config.emit_obj && config.obj_needs_as;
     let write_obj = config.emit_obj && !config.obj_is_bitcode;
     let copy_bc_to_obj = config.emit_obj && config.obj_is_bitcode;
 
     let bc_out = output_names.temp_path(OutputType::Bitcode, module_name);
-    let asm_out = output_names.temp_path(OutputType::Assembly, module_name);
     let obj_out = output_names.temp_path(OutputType::Object, module_name);
 
     if write_bc {
@@ -589,25 +578,27 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
             })
         }
 
-        if write_asm {
+        if config.emit_asm {
+            let path = output_names.temp_path(OutputType::Assembly, module_name);
+
             // We can't use the same module for asm and binary output, because that triggers
             // various errors like invalid IR or broken binaries, so we might have to clone the
             // module to produce the asm output
-            let llmod = if config.emit_obj && !config.obj_needs_as {
+            let llmod = if config.emit_obj {
                 llvm::LLVMCloneModule(llmod)
             } else {
                 llmod
             };
             with_codegen(tm, llmod, config.no_builtins, |cpm| {
-                write_output_file(cgcx.handler, tm, cpm, llmod, &asm_out,
+                write_output_file(cgcx.handler, tm, cpm, llmod, &path,
                                   llvm::FileType::AssemblyFile);
             });
-            if config.emit_obj && !config.obj_needs_as {
+            if config.emit_obj {
                 llvm::LLVMDisposeModule(llmod);
             }
         }
 
-        if write_obj && !config.obj_needs_as {
+        if write_obj {
             with_codegen(tm, llmod, config.no_builtins, |cpm| {
                 write_output_file(cgcx.handler, tm, cpm, llmod, &obj_out,
                                   llvm::FileType::ObjectFile);
@@ -622,59 +613,6 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
         }
     }
 
-    if config.obj_needs_as {
-        // XXX most of the logic here has been copied from the link_natively
-        // function (src/librustc_trans/back/link.rs)
-        // TODO don't hardcode, maybe expose as a `as` field in the target
-        // specification
-        // TODO how to properly access `sess` here?
-        let mut cmd = Command::new("msp430-as");
-        cmd.arg("-o");
-        cmd.arg(obj_out);
-        cmd.arg(&asm_out);
-
-        info!("{:?}", &cmd);
-        // let prog = time(sess.time_passes(), "running assembler",
-        //                 || cmd.output());
-        let prog = cmd.output();
-        match prog {
-            Ok(prog) => {
-                fn escape_string(s: &[u8]) -> String {
-                    str::from_utf8(s).map(|s| s.to_owned())
-                        .unwrap_or_else(|_| {
-                            let mut x = "Non-UTF-8 output: ".to_string();
-                            x.extend(s.iter()
-                                     .flat_map(|&b| ascii::escape_default(b))
-                                     .map(|b| char::from_u32(b as u32).unwrap()));
-                            x
-                        })
-                }
-                if !prog.status.success() {
-                    let mut output = prog.stderr.clone();
-                    output.extend_from_slice(&prog.stdout);
-                    // sess.struct_err(&format!("assembling with `msp430-as` failed: {}",
-                    //                          prog.status))
-                    //     .note(&format!("{:?}", &cmd))
-                    //     .note(&escape_string(&output[..]))
-                    //     .emit();
-                    // sess.abort_if_errors();
-                }
-                info!("linker stderr:\n{}", escape_string(&prog.stderr[..]));
-                info!("linker stdout:\n{}", escape_string(&prog.stdout[..]));
-            },
-            Err(_) => {
-                // sess.struct_err(&format!("could not exec the assembler `msp430-as`: {}", e))
-                //     .note(&format!("{:?}", &cmd))
-                //     .emit();
-                // if e.kind() == io::ErrorKind::NotFound {
-                //     sess.note_without_error("MSP430 targets depend on the MSP430 assembler \
-                //                              but `msp430-as` was not found");
-                // }
-                // sess.abort_if_errors();
-            },
-        }
-    }
-
     if rm_bc {
         debug!("removing_bitcode {:?}", bc_out);
         if let Err(e) = fs::remove_file(&bc_out) {
@@ -682,13 +620,6 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
         }
     }
 
-    if rm_asm {
-        debug!("removing_assembly {:?}", bc_out);
-        if let Err(e) = fs::remove_file(&asm_out) {
-            cgcx.handler.err(&format!("failed to remove assembly: {}", e));
-        }
-    }
-
     llvm::LLVMRustDisposeTargetMachine(tm);
 }