about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-04-22 17:36:49 -0700
committerbors <bors@rust-lang.org>2013-04-22 17:36:49 -0700
commit773f7e75603a0bb99682a761d5b77577bb876c3c (patch)
treef84bec585a2ebd07a9480d365f44ace9c0d2ebda
parent05f9586d0682e87362a5783edc7e5238094b8ae2 (diff)
parentda4bc490e6fcd8042f6ce49da0039d38c22d37f4 (diff)
downloadrust-773f7e75603a0bb99682a761d5b77577bb876c3c.tar.gz
rust-773f7e75603a0bb99682a761d5b77577bb876c3c.zip
auto merge of #5996 : sanxiyn/rust/target-feature, r=graydon
Fix #1879.
-rw-r--r--src/librustc/back/link.rs106
-rw-r--r--src/librustc/driver/driver.rs9
-rw-r--r--src/librustc/driver/session.rs2
-rw-r--r--src/librustc/lib/llvm.rs3
-rw-r--r--src/rustllvm/RustWrapper.cpp3
5 files changed, 64 insertions, 59 deletions
diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs
index a176b0163a4..99ea0bc0c86 100644
--- a/src/librustc/back/link.rs
+++ b/src/librustc/back/link.rs
@@ -61,23 +61,32 @@ pub fn llvm_err(sess: Session, msg: ~str) -> ! {
 
 pub fn WriteOutputFile(sess: Session,
         PM: lib::llvm::PassManagerRef, M: ModuleRef,
-        Triple: *c_char,
+        Triple: &str,
+        Feature: &str,
+        Output: &str,
         // FIXME: When #2334 is fixed, change
         // c_uint to FileType
-        Output: *c_char, FileType: c_uint,
+        FileType: c_uint,
         OptLevel: c_int,
         EnableSegmentedStacks: bool) {
     unsafe {
-        let result = llvm::LLVMRustWriteOutputFile(
-                PM,
-                M,
-                Triple,
-                Output,
-                FileType,
-                OptLevel,
-                EnableSegmentedStacks);
-        if (!result) {
-            llvm_err(sess, ~"Could not write output");
+        do str::as_c_str(Triple) |Triple| {
+            do str::as_c_str(Feature) |Feature| {
+                do str::as_c_str(Output) |Output| {
+                    let result = llvm::LLVMRustWriteOutputFile(
+                            PM,
+                            M,
+                            Triple,
+                            Feature,
+                            Output,
+                            FileType,
+                            OptLevel,
+                            EnableSegmentedStacks);
+                    if (!result) {
+                        llvm_err(sess, ~"Could not write output");
+                    }
+                }
+            }
         }
     }
 }
@@ -310,66 +319,49 @@ pub mod write {
                         llvm::LLVMWriteBitcodeToFile(llmod, buf)
                     });
                     pm = mk_pass_manager();
-                    // Save the assembly file if -S is used
 
+                    // Save the assembly file if -S is used
                     if output_type == output_type_assembly {
-                        let _: () = str::as_c_str(
+                        WriteOutputFile(
+                            sess,
+                            pm.llpm,
+                            llmod,
                             sess.targ_cfg.target_strs.target_triple,
-                            |buf_t| {
-                                str::as_c_str(output.to_str(), |buf_o| {
-                                    WriteOutputFile(
-                                        sess,
-                                        pm.llpm,
-                                        llmod,
-                                        buf_t,
-                                        buf_o,
-                                        lib::llvm::AssemblyFile as c_uint,
-                                        CodeGenOptLevel,
-                                        true)
-                                })
-                            });
+                            opts.target_feature,
+                            output.to_str(),
+                            lib::llvm::AssemblyFile as c_uint,
+                            CodeGenOptLevel,
+                            true);
                     }
 
-
                     // Save the object file for -c or --save-temps alone
                     // This .o is needed when an exe is built
                     if output_type == output_type_object ||
                            output_type == output_type_exe {
-                        let _: () = str::as_c_str(
+                        WriteOutputFile(
+                            sess,
+                            pm.llpm,
+                            llmod,
                             sess.targ_cfg.target_strs.target_triple,
-                            |buf_t| {
-                                str::as_c_str(output.to_str(), |buf_o| {
-                                    WriteOutputFile(
-                                        sess,
-                                        pm.llpm,
-                                        llmod,
-                                        buf_t,
-                                        buf_o,
-                                        lib::llvm::ObjectFile as c_uint,
-                                        CodeGenOptLevel,
-                                        true)
-                                })
-                            });
+                            opts.target_feature,
+                            output.to_str(),
+                            lib::llvm::ObjectFile as c_uint,
+                            CodeGenOptLevel,
+                            true);
                     }
                 } else {
                     // If we aren't saving temps then just output the file
                     // type corresponding to the '-c' or '-S' flag used
-
-                    let _: () = str::as_c_str(
+                    WriteOutputFile(
+                        sess,
+                        pm.llpm,
+                        llmod,
                         sess.targ_cfg.target_strs.target_triple,
-                        |buf_t| {
-                            str::as_c_str(output.to_str(), |buf_o| {
-                                WriteOutputFile(
-                                    sess,
-                                    pm.llpm,
-                                    llmod,
-                                    buf_t,
-                                    buf_o,
-                                    FileType as c_uint,
-                                    CodeGenOptLevel,
-                                    true)
-                            })
-                        });
+                        opts.target_feature,
+                        output.to_str(),
+                        FileType as c_uint,
+                        CodeGenOptLevel,
+                        true);
                 }
                 // Clean up and return
 
diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs
index c4f37c2170d..7110382bb55 100644
--- a/src/librustc/driver/driver.rs
+++ b/src/librustc/driver/driver.rs
@@ -599,6 +599,7 @@ pub fn build_session_options(binary: @~str,
     let sysroot_opt = getopts::opt_maybe_str(matches, ~"sysroot");
     let sysroot_opt = sysroot_opt.map(|m| Path(*m));
     let target_opt = getopts::opt_maybe_str(matches, ~"target");
+    let target_feature_opt = getopts::opt_maybe_str(matches, ~"target-feature");
     let save_temps = getopts::opt_present(matches, ~"save-temps");
     match output_type {
       // unless we're emitting huamn-readable assembly, omit comments.
@@ -637,6 +638,10 @@ pub fn build_session_options(binary: @~str,
             None => host_triple(),
             Some(s) => s
         };
+    let target_feature = match target_feature_opt {
+        None => ~"",
+        Some(s) => s
+    };
 
     let addl_lib_search_paths =
         getopts::opt_strs(matches, ~"L")
@@ -659,6 +664,7 @@ pub fn build_session_options(binary: @~str,
         addl_lib_search_paths: addl_lib_search_paths,
         maybe_sysroot: sysroot_opt,
         target_triple: target,
+        target_feature: target_feature,
         cfg: cfg,
         binary: binary,
         test: test,
@@ -769,6 +775,9 @@ pub fn optgroups() -> ~[getopts::groups::OptGroup] {
                         ~"Target triple cpu-manufacturer-kernel[-os]
                           to compile for (see chapter 3.4 of http://www.sourceware.org/autobook/
                           for detail)", ~"TRIPLE"),
+  optopt(~"", ~"target-feature",
+                        ~"Target specific attributes (llc -mattr=help
+                          for detail)", ~"FEATURE"),
   optopt(~"", ~"android-cross-path",
          ~"The path to the Android NDK", "PATH"),
   optmulti(~"W", ~"warn",
diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs
index 1912c922524..a2bbbca0c5a 100644
--- a/src/librustc/driver/session.rs
+++ b/src/librustc/driver/session.rs
@@ -126,6 +126,7 @@ pub struct options {
     addl_lib_search_paths: ~[Path],
     maybe_sysroot: Option<Path>,
     target_triple: ~str,
+    target_feature: ~str,
     // User-specified cfg meta items. The compiler itself will add additional
     // items to the crate config, and during parsing the entire crate config
     // will be added to the crate AST node.  This should not be used for
@@ -302,6 +303,7 @@ pub fn basic_options() -> @options {
         addl_lib_search_paths: ~[],
         maybe_sysroot: None,
         target_triple: host_triple(),
+        target_feature: ~"",
         cfg: ~[],
         binary: @~"rustc",
         test: false,
diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs
index 369e6aeb4a5..1ab84c7978c 100644
--- a/src/librustc/lib/llvm.rs
+++ b/src/librustc/lib/llvm.rs
@@ -1799,9 +1799,10 @@ pub mod llvm {
         pub unsafe fn LLVMRustWriteOutputFile(PM: PassManagerRef,
                                               M: ModuleRef,
                                               Triple: *c_char,
+                                              Feature: *c_char,
+                                              Output: *c_char,
                                               // FIXME: When #2334 is fixed,
                                               // change c_uint to FileType
-                                              Output: *c_char,
                                               FileType: c_uint,
                                               OptLevel: c_int,
                                               EnableSegmentedStacks: bool)
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index 141276e86f0..451a390876c 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -434,6 +434,7 @@ extern "C" bool
 LLVMRustWriteOutputFile(LLVMPassManagerRef PMR,
                         LLVMModuleRef M,
                         const char *triple,
+                        const char *feature,
                         const char *path,
                         TargetMachine::CodeGenFileType FileType,
                         CodeGenOpt::Level OptLevel,
@@ -461,7 +462,7 @@ LLVMRustWriteOutputFile(LLVMPassManagerRef PMR,
 
   std::string Err;
   std::string Trip(Triple::normalize(triple));
-  std::string FeaturesStr;
+  std::string FeaturesStr(feature);
   std::string CPUStr("generic");
   const Target *TheTarget = TargetRegistry::lookupTarget(Trip, Err);
   TargetMachine *Target =