From 5d241c23b80c2cc7b1e614e0ace2393399d39249 Mon Sep 17 00:00:00 2001 From: Svetoslav Neykov Date: Wed, 11 Dec 2013 22:47:03 +0200 Subject: [PATCH 1/4] Add support for bare-metal - None OS as a possible target. --- src/librustc/back/arm.rs | 10 +++++++++- src/librustc/back/link.rs | 3 ++- src/librustc/back/mips.rs | 10 +++++++++- src/librustc/back/rpath.rs | 2 +- src/librustc/back/x86.rs | 6 +++++- src/librustc/back/x86_64.rs | 6 ++++++ src/librustc/driver/driver.rs | 6 ++++-- src/librustc/driver/session.rs | 3 ++- src/librustc/metadata/loader.rs | 12 ++++++++---- src/libstd/os.rs | 12 ++++++++++++ src/libsyntax/abi.rs | 2 +- 11 files changed, 59 insertions(+), 13 deletions(-) diff --git a/src/librustc/back/arm.rs b/src/librustc/back/arm.rs index c155f4bd15b89..0d4a8c5416280 100644 --- a/src/librustc/back/arm.rs +++ b/src/librustc/back/arm.rs @@ -59,7 +59,15 @@ pub fn get_target_strs(target_triple: ~str, target_os: abi::Os) -> target_strs:: "-v64:64:64-v128:64:128" + "-a0:0:64-n32" } - }, + + abi::OsNone => { + ~"e-p:32:32:32" + + "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64" + + "-f32:32:32-f64:64:64" + + "-v64:64:64-v128:64:128" + + "-a0:0:64-n32" + } + }, target_triple: target_triple, diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 786b463c37ec2..f552e45a2c7a2 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -28,7 +28,7 @@ use util::sha2::{Digest, Sha256}; use std::c_str::ToCStr; use std::char; -use std::os::consts::{macos, freebsd, linux, android, win32}; +use std::os::consts::{macos, freebsd, linux, android, win32, none}; use std::ptr; use std::run; use std::str; @@ -767,6 +767,7 @@ fn link_binary_output(sess: Session, abi::OsLinux => (linux::DLL_PREFIX, linux::DLL_SUFFIX), abi::OsAndroid => (android::DLL_PREFIX, android::DLL_SUFFIX), abi::OsFreebsd => (freebsd::DLL_PREFIX, freebsd::DLL_SUFFIX), + abi::OsNone => (none::DLL_PREFIX, none::DLL_SUFFIX), }; out_filename.with_filename(format!("{}{}{}", prefix, libname, suffix)) } diff --git a/src/librustc/back/mips.rs b/src/librustc/back/mips.rs index ce716f6f94b35..20e4f2f8d792e 100644 --- a/src/librustc/back/mips.rs +++ b/src/librustc/back/mips.rs @@ -59,7 +59,15 @@ pub fn get_target_strs(target_triple: ~str, target_os: abi::Os) -> target_strs:: "-v64:64:64-v128:64:128" + "-a0:0:64-n32" } - }, + + abi::OsNone => { + ~"e-p:32:32:32" + + "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64" + + "-f32:32:32-f64:64:64" + + "-v64:64:64-v128:64:128" + + "-a0:0:64-n32" + } + }, target_triple: target_triple, diff --git a/src/librustc/back/rpath.rs b/src/librustc/back/rpath.rs index dae4a9df3da96..a1177639362b2 100644 --- a/src/librustc/back/rpath.rs +++ b/src/librustc/back/rpath.rs @@ -129,7 +129,7 @@ pub fn get_rpath_relative_to_output(os: abi::Os, // Mac doesn't appear to support $ORIGIN let prefix = match os { - abi::OsAndroid | abi::OsLinux | abi::OsFreebsd + abi::OsAndroid | abi::OsLinux | abi::OsFreebsd | abi::OsNone => "$ORIGIN", abi::OsMacos => "@loader_path", abi::OsWin32 => unreachable!() diff --git a/src/librustc/back/x86.rs b/src/librustc/back/x86.rs index de0372b83b972..ab6492cb73d26 100644 --- a/src/librustc/back/x86.rs +++ b/src/librustc/back/x86.rs @@ -42,7 +42,11 @@ pub fn get_target_strs(target_triple: ~str, target_os: abi::Os) -> target_strs:: abi::OsFreebsd => { ~"e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32" } - }, + + abi::OsNone => { + ~"e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32" + } + }, target_triple: target_triple, diff --git a/src/librustc/back/x86_64.rs b/src/librustc/back/x86_64.rs index dce4de3dce3c1..6ea643bf7966f 100644 --- a/src/librustc/back/x86_64.rs +++ b/src/librustc/back/x86_64.rs @@ -50,6 +50,12 @@ pub fn get_target_strs(target_triple: ~str, target_os: abi::Os) -> target_strs:: "f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-"+ "s0:64:64-f80:128:128-n8:16:32:64-S128" } + + abi::OsNone => { + ~"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"+ + "f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-"+ + "s0:64:64-f80:128:128-n8:16:32:64-S128" + } }, target_triple: target_triple, diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index ec0424994075d..914e95bd9fcc2 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -73,7 +73,8 @@ pub fn default_configuration(sess: Session) -> abi::OsMacos => @"macos", abi::OsLinux => @"linux", abi::OsAndroid => @"android", - abi::OsFreebsd => @"freebsd" + abi::OsFreebsd => @"freebsd", + abi::OsNone => @"none" }; // ARM is bi-endian, however using NDK seems to default @@ -554,7 +555,8 @@ static os_names : &'static [(&'static str, abi::Os)] = &'static [ ("darwin", abi::OsMacos), ("android", abi::OsAndroid), ("linux", abi::OsLinux), - ("freebsd", abi::OsFreebsd)]; + ("freebsd", abi::OsFreebsd), + ("none", abi::OsNone)]; pub fn get_arch(triple: &str) -> Option { for &(arch, abi) in architecture_abis.iter() { diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 30d5b7780cf92..4a75cb22f892a 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -446,6 +446,7 @@ pub fn sess_os_to_meta_os(os: abi::Os) -> metadata::loader::Os { abi::OsLinux => loader::OsLinux, abi::OsAndroid => loader::OsAndroid, abi::OsMacos => loader::OsMacos, - abi::OsFreebsd => loader::OsFreebsd + abi::OsFreebsd => loader::OsFreebsd, + abi::OsNone => loader::OsNone } } diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index dd5d082ddb7c8..ab7d61ad6aae1 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -29,7 +29,7 @@ use std::cast; use std::io; use std::num; use std::option; -use std::os::consts::{macos, freebsd, linux, android, win32}; +use std::os::consts::{macos, freebsd, linux, android, win32, none}; use std::ptr; use std::str; use std::vec; @@ -40,7 +40,8 @@ pub enum Os { OsWin32, OsLinux, OsAndroid, - OsFreebsd + OsFreebsd, + OsNone } pub struct Context { @@ -217,6 +218,7 @@ impl Context { OsLinux => (linux::DLL_PREFIX, linux::DLL_SUFFIX), OsAndroid => (android::DLL_PREFIX, android::DLL_SUFFIX), OsFreebsd => (freebsd::DLL_PREFIX, freebsd::DLL_SUFFIX), + OsNone => (none::DLL_PREFIX, none::DLL_SUFFIX), } } } @@ -302,7 +304,8 @@ pub fn meta_section_name(os: Os) -> &'static str { OsWin32 => ".note.rustc", OsLinux => ".note.rustc", OsAndroid => ".note.rustc", - OsFreebsd => ".note.rustc" + OsFreebsd => ".note.rustc", + OsNone => ".note.rustc" } } @@ -312,7 +315,8 @@ pub fn read_meta_section_name(os: Os) -> &'static str { OsWin32 => ".note.rustc", OsLinux => ".note.rustc", OsAndroid => ".note.rustc", - OsFreebsd => ".note.rustc" + OsFreebsd => ".note.rustc", + OsNone => ".note.rustc" } } diff --git a/src/libstd/os.rs b/src/libstd/os.rs index bcd353bab7af1..7553a65f043c3 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -1162,6 +1162,9 @@ pub mod consts { #[cfg(target_os = "win32")] pub use os::consts::win32::*; + #[cfg(target_os = "none")] + pub use os::consts::none::*; + #[cfg(target_arch = "x86")] pub use os::consts::x86::*; @@ -1227,6 +1230,15 @@ pub mod consts { pub static EXE_EXTENSION: &'static str = "exe"; } + pub mod none { + pub static SYSNAME: &'static str = "none"; + pub static DLL_PREFIX: &'static str = "lib"; + pub static DLL_SUFFIX: &'static str = ".so"; + pub static DLL_EXTENSION: &'static str = "so"; + pub static EXE_SUFFIX: &'static str = ""; + pub static EXE_EXTENSION: &'static str = ""; + } + pub mod x86 { pub static ARCH: &'static str = "x86"; diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs index 9f69379f3c58c..305ac2e173fe4 100644 --- a/src/libsyntax/abi.rs +++ b/src/libsyntax/abi.rs @@ -11,7 +11,7 @@ use std::to_bytes; #[deriving(Eq)] -pub enum Os { OsWin32, OsMacos, OsLinux, OsAndroid, OsFreebsd, } +pub enum Os { OsWin32, OsMacos, OsLinux, OsAndroid, OsFreebsd, OsNone, } #[deriving(Eq)] pub enum Abi { From 33cd8275a33f1e9e946951b57c0c82c4314e6932 Mon Sep 17 00:00:00 2001 From: Svetoslav Neykov Date: Wed, 11 Dec 2013 23:19:12 +0200 Subject: [PATCH 2/4] Add support for Thumb architecture as a possible target. --- src/librustc/back/thumb.rs | 77 ++++++++++++++++++++++++++++++ src/librustc/driver/driver.rs | 6 ++- src/librustc/lib.rs | 1 + src/librustc/middle/trans/adt.rs | 4 +- src/librustc/middle/trans/asm.rs | 1 + src/librustc/middle/trans/base.rs | 6 +-- src/librustc/middle/trans/cabi.rs | 4 +- src/librustc/middle/trans/type_.rs | 4 +- src/librustpkg/api.rs | 2 + src/libsyntax/abi.rs | 1 + 10 files changed, 96 insertions(+), 10 deletions(-) create mode 100644 src/librustc/back/thumb.rs diff --git a/src/librustc/back/thumb.rs b/src/librustc/back/thumb.rs new file mode 100644 index 0000000000000..170248fc5f6dd --- /dev/null +++ b/src/librustc/back/thumb.rs @@ -0,0 +1,77 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use back::target_strs; +use driver::session::sess_os_to_meta_os; +use metadata::loader::meta_section_name; +use syntax::abi; + +pub fn get_target_strs(target_triple: ~str, target_os: abi::Os) -> target_strs::t { + return target_strs::t { + module_asm: ~"", + + meta_sect_name: meta_section_name(sess_os_to_meta_os(target_os)).to_owned(), + + data_layout: match target_os { + abi::OsMacos => { + ~"e-p:32:32:32" + + "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64" + + "-f32:32:32-f64:64:64" + + "-v64:64:64-v128:64:128" + + "-a0:0:64-n32" + } + + abi::OsWin32 => { + ~"e-p:32:32:32" + + "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64" + + "-f32:32:32-f64:64:64" + + "-v64:64:64-v128:64:128" + + "-a0:0:64-n32" + } + + abi::OsLinux => { + ~"e-p:32:32:32" + + "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64" + + "-f32:32:32-f64:64:64" + + "-v64:64:64-v128:64:128" + + "-a0:0:64-n32" + } + + abi::OsAndroid => { + ~"e-p:32:32:32" + + "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64" + + "-f32:32:32-f64:64:64" + + "-v64:64:64-v128:64:128" + + "-a0:0:64-n32" + } + + abi::OsFreebsd => { + ~"e-p:32:32:32" + + "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64" + + "-f32:32:32-f64:64:64" + + "-v64:64:64-v128:64:128" + + "-a0:0:64-n32" + } + + abi::OsNone => { + ~"e-p:32:32:32" + + "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64" + + "-f32:32:32-f64:64:64" + + "-v64:64:64-v128:64:128" + + "-a0:0:64-n32" + } + + }, + + target_triple: target_triple, + + cc_args: ~[~"-mthumb"] + }; +} diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 914e95bd9fcc2..ade501b65bbc3 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -10,7 +10,7 @@ use back::link; -use back::{arm, x86, x86_64, mips}; +use back::{arm, thumb, x86, x86_64, mips}; use driver::session::{Aggressive, OutputExecutable}; use driver::session::{Session, Session_, No, Less, Default}; use driver::session; @@ -83,6 +83,7 @@ pub fn default_configuration(sess: Session) -> abi::X86 => (@"little", @"x86", @"32"), abi::X86_64 => (@"little", @"x86_64", @"64"), abi::Arm => (@"little", @"arm", @"32"), + abi::Thumb => (@"little", @"thumb", @"32"), abi::Mips => (@"big", @"mips", @"32") }; @@ -574,6 +575,7 @@ static architecture_abis : &'static [(&'static str, abi::Architecture)] = &'stat ("x86_64", abi::X86_64), ("arm", abi::Arm), + ("thumb", abi::Thumb), ("xscale", abi::Arm), ("mips", abi::Mips)]; @@ -594,6 +596,7 @@ pub fn build_target_config(sopts: @session::options, abi::X86 => (ast::ty_i32, ast::ty_u32), abi::X86_64 => (ast::ty_i64, ast::ty_u64), abi::Arm => (ast::ty_i32, ast::ty_u32), + abi::Thumb => (ast::ty_i32, ast::ty_u32), abi::Mips => (ast::ty_i32, ast::ty_u32) }; let target_triple = sopts.target_triple.clone(); @@ -601,6 +604,7 @@ pub fn build_target_config(sopts: @session::options, abi::X86 => x86::get_target_strs(target_triple, os), abi::X86_64 => x86_64::get_target_strs(target_triple, os), abi::Arm => arm::get_target_strs(target_triple, os), + abi::Thumb => thumb::get_target_strs(target_triple, os), abi::Mips => mips::get_target_strs(target_triple, os) }; let target_cfg = @session::config { diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 090329bc4a09b..dea4d915d7de3 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -96,6 +96,7 @@ pub mod back { pub mod abi; pub mod upcall; pub mod arm; + pub mod thumb; pub mod mips; pub mod x86; pub mod x86_64; diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index 7893a63fa5d53..e71d2d07c4c9e 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -55,7 +55,7 @@ use middle::trans::machine; use middle::trans::type_of; use middle::ty; use middle::ty::Disr; -use syntax::abi::{X86, X86_64, Arm, Mips}; +use syntax::abi::{X86, X86_64, Arm, Thumb, Mips}; use syntax::ast; use syntax::attr; use syntax::attr::IntType; @@ -318,7 +318,7 @@ fn range_to_inttype(cx: &mut CrateContext, hint: Hint, bounds: &IntBounds) -> In // WARNING: the ARM EABI has two variants; the one corresponding to `at_least_32` // appears to be used on Linux and NetBSD, but some systems may use the variant // corresponding to `choose_shortest`. However, we don't run on those yet...? - Arm => at_least_32, + Arm | Thumb => at_least_32, Mips => at_least_32, } } diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs index 7b936b61976bc..198c425d68f7f 100644 --- a/src/librustc/middle/trans/asm.rs +++ b/src/librustc/middle/trans/asm.rs @@ -126,6 +126,7 @@ pub fn trans_inline_asm(bcx: @mut Block, ia: &ast::inline_asm) -> @mut Block { // Basically what clang does #[cfg(target_arch = "arm")] +#[cfg(target_arch = "thumb")] #[cfg(target_arch = "mips")] fn getClobbers() -> ~str { ~"" diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index d6fc48b52ea2c..7458683226349 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -84,7 +84,7 @@ use syntax::parse::token::{special_idents}; use syntax::print::pprust::stmt_to_str; use syntax::{ast, ast_util, codemap, ast_map}; use syntax::attr::AttrMetaMethods; -use syntax::abi::{X86, X86_64, Arm, Mips, Rust, RustIntrinsic, OsWin32, OsAndroid}; +use syntax::abi::{X86, X86_64, Arm, Thumb, Mips, Rust, RustIntrinsic, OsWin32, OsAndroid}; use syntax::visit; use syntax::visit::Visitor; @@ -1471,7 +1471,7 @@ pub fn call_memcpy(cx: @mut Block, dst: ValueRef, src: ValueRef, n_bytes: ValueR let _icx = push_ctxt("call_memcpy"); let ccx = cx.ccx(); let key = match ccx.sess.targ_cfg.arch { - X86 | Arm | Mips => "llvm.memcpy.p0i8.p0i8.i32", + X86 | Arm | Thumb | Mips => "llvm.memcpy.p0i8.p0i8.i32", X86_64 => "llvm.memcpy.p0i8.p0i8.i64" }; let memcpy = ccx.intrinsics.get_copy(&key); @@ -1515,7 +1515,7 @@ pub fn memzero(b: &Builder, llptr: ValueRef, ty: Type) { let ccx = b.ccx; let intrinsic_key = match ccx.sess.targ_cfg.arch { - X86 | Arm | Mips => "llvm.memset.p0i8.i32", + X86 | Arm | Thumb | Mips => "llvm.memset.p0i8.i32", X86_64 => "llvm.memset.p0i8.i64" }; diff --git a/src/librustc/middle/trans/cabi.rs b/src/librustc/middle/trans/cabi.rs index 8648bf6f34803..869ac2a89a03c 100644 --- a/src/librustc/middle/trans/cabi.rs +++ b/src/librustc/middle/trans/cabi.rs @@ -16,7 +16,7 @@ use middle::trans::cabi_x86_64; use middle::trans::cabi_arm; use middle::trans::cabi_mips; use middle::trans::type_::Type; -use syntax::abi::{X86, X86_64, Arm, Mips}; +use syntax::abi::{X86, X86_64, Arm, Thumb, Mips}; #[deriving(Clone, Eq)] pub enum ArgKind { @@ -96,7 +96,7 @@ pub fn compute_abi_info(ccx: &mut CrateContext, match ccx.sess.targ_cfg.arch { X86 => cabi_x86::compute_abi_info(ccx, atys, rty, ret_def), X86_64 => cabi_x86_64::compute_abi_info(ccx, atys, rty, ret_def), - Arm => cabi_arm::compute_abi_info(ccx, atys, rty, ret_def), + Arm | Thumb => cabi_arm::compute_abi_info(ccx, atys, rty, ret_def), Mips => cabi_mips::compute_abi_info(ccx, atys, rty, ret_def), } } diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index 3e0761e214ce8..2f00687433b5c 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -19,7 +19,7 @@ use middle::trans::context::CrateContext; use middle::trans::base; use syntax::ast; -use syntax::abi::{Architecture, X86, X86_64, Arm, Mips}; +use syntax::abi::{Architecture, X86, X86_64, Arm, Thumb, Mips}; use std::c_str::ToCStr; use std::vec; @@ -106,7 +106,7 @@ impl Type { pub fn int(arch: Architecture) -> Type { match arch { - X86 | Arm | Mips => Type::i32(), + X86 | Arm | Thumb | Mips => Type::i32(), X86_64 => Type::i64() } } diff --git a/src/librustpkg/api.rs b/src/librustpkg/api.rs index 0d0d0b7c4c79d..82a9387943a0b 100644 --- a/src/librustpkg/api.rs +++ b/src/librustpkg/api.rs @@ -30,6 +30,8 @@ use extra::treemap::TreeMap; // A little sad -- duplicated from rustc::back::* #[cfg(target_arch = "arm")] fn cc_args() -> ~[~str] { ~[~"-marm"] } +#[cfg(target_arch = "thumb")] +fn cc_args() -> ~[~str] { ~[~"-mthumb"] } #[cfg(target_arch = "mips")] fn cc_args() -> ~[~str] { ~[] } #[cfg(target_arch = "x86")] diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs index 305ac2e173fe4..0a815e533da14 100644 --- a/src/libsyntax/abi.rs +++ b/src/libsyntax/abi.rs @@ -40,6 +40,7 @@ pub enum Architecture { X86, X86_64, Arm, + Thumb, Mips } From 4c22e3a8eda318e0fab3d2b81f03b5aa4e628554 Mon Sep 17 00:00:00 2001 From: Svetoslav Neykov Date: Thu, 12 Dec 2013 23:05:32 +0200 Subject: [PATCH 3/4] Disable inapropriate funcitonality for bare-metal systems - PIC, stack unwinding, segmented stacks. --- src/librustc/back/link.rs | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index f552e45a2c7a2..03b7af3a10d25 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -100,6 +100,7 @@ pub mod write { use std::path::Path; use std::run; use std::str; + use syntax::abi; pub fn run_passes(sess: Session, trans: &CrateTranslation, @@ -148,15 +149,24 @@ pub mod write { }; let use_softfp = sess.opts.debugging_opts & session::use_softfp != 0; + //For embedded targets PIC doesn't make sense. + //The code layout is static, defined by the linker. + let reloc_mode = match sess.targ_cfg.os { + abi::OsNone => lib::llvm::RelocDynamicNoPic, + _ => lib::llvm::RelocPIC + }; + //Segmented stacks not supported on bare-metal. + let enable_segmented_stacks = (sess.targ_cfg.os != abi::OsNone); + let tm = sess.targ_cfg.target_strs.target_triple.with_c_str(|T| { sess.opts.target_cpu.with_c_str(|CPU| { sess.opts.target_feature.with_c_str(|Features| { llvm::LLVMRustCreateTargetMachine( T, CPU, Features, lib::llvm::CodeModelDefault, - lib::llvm::RelocPIC, + reloc_mode, OptLevel, - true, + enable_segmented_stacks, use_softfp ) }) @@ -336,8 +346,14 @@ pub mod write { llvm_c_strs.push(s); }; add("rustc"); // fake program name - add("-arm-enable-ehabi"); - add("-arm-enable-ehabi-descriptors"); + + //Embedded targets don't support the std library and therefore + //the task system where unwinding is used. + if(sess.targ_cfg.os != abi::OsNone) { + add("-arm-enable-ehabi"); + add("-arm-enable-ehabi-descriptors"); + } + if vectorize_loop { add("-vectorize-loops"); } if vectorize_slp { add("-vectorize-slp"); } if sess.time_llvm_passes() { add("-time-passes"); } @@ -1020,8 +1036,11 @@ fn link_args(sess: Session, ~"-L/usr/local/lib/gcc44"]); } - // Stack growth requires statically linking a __morestack function - args.push(~"-lmorestack"); + //Segmented stacks not supported on bare-metal. + if sess.targ_cfg.os != abi::OsNone { + // Stack growth requires statically linking a __morestack function + args.push(~"-lmorestack"); + } // FIXME (#2397): At some point we want to rpath our guesses as to // where extern libraries might live, based on the From f848d6292b057be72f1f3716044224e408dc63d5 Mon Sep 17 00:00:00 2001 From: Svetoslav Neykov Date: Thu, 12 Dec 2013 23:06:16 +0200 Subject: [PATCH 4/4] Add command line option to enable hard FP ABI. --- src/librustc/back/link.rs | 11 +++++++++-- src/librustc/driver/session.rs | 2 ++ src/librustc/lib/llvm.rs | 11 +++++++++-- src/rustllvm/PassWrapper.cpp | 13 ++++++------- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 03b7af3a10d25..306c301332372 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -147,7 +147,14 @@ pub mod write { session::Default => lib::llvm::CodeGenLevelDefault, session::Aggressive => lib::llvm::CodeGenLevelAggressive, }; - let use_softfp = sess.opts.debugging_opts & session::use_softfp != 0; + let fp_abi = + if (sess.opts.debugging_opts & session::use_hardfp != 0) { + lib::llvm::FloatABIHard + } else if (sess.opts.debugging_opts & session::use_softfp != 0) { + lib::llvm::FloatABISoft + } else { + lib::llvm::FloatABIDefault + }; //For embedded targets PIC doesn't make sense. //The code layout is static, defined by the linker. @@ -167,7 +174,7 @@ pub mod write { reloc_mode, OptLevel, enable_segmented_stacks, - use_softfp + fp_abi ) }) }) diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 4a75cb22f892a..3583e3374620b 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -69,6 +69,7 @@ pub static gen_crate_map: uint = 1 << 27; pub static prefer_dynamic: uint = 1 << 28; pub static no_integrated_as: uint = 1 << 29; pub static lto: uint = 1 << 30; +pub static use_hardfp: uint = 1 << 31; pub fn debugging_opts_map() -> ~[(&'static str, &'static str, uint)] { ~[("verbose", "in general, enable more debug printouts", verbose), @@ -118,6 +119,7 @@ pub fn debugging_opts_map() -> ~[(&'static str, &'static str, uint)] { "Don't run LLVM's SLP vectorization passes", no_vectorize_slp), ("soft-float", "Generate software floating point library calls", use_softfp), + ("hard-float", "Use FP hardware", use_hardfp), ("gen-crate-map", "Force generation of a toplevel crate map", gen_crate_map), ("prefer-dynamic", "Prefer dynamic linking to static linking", prefer_dynamic), ("no-integrated-as", diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 7039eced9769f..aea53e68f0f50 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -224,6 +224,13 @@ pub enum CodeGenModel { CodeModelLarge = 5, } +#[repr(C)] +pub enum FloatABI { + FloatABIDefault = 0, + FloatABISoft = 1, + FloatABIHard = 2, +} + // Opaque pointer types pub enum Module_opaque {} pub type ModuleRef = *Module_opaque; @@ -301,7 +308,7 @@ pub mod llvm { use super::{ObjectFileRef, Opcode, PassManagerRef, PassManagerBuilderRef}; use super::{SectionIteratorRef, TargetDataRef, TypeKind, TypeRef, UseRef}; use super::{ValueRef, TargetMachineRef, FileType}; - use super::{CodeGenModel, RelocMode, CodeGenOptLevel}; + use super::{CodeGenModel, RelocMode, CodeGenOptLevel, FloatABI}; use super::debuginfo::*; use std::libc::{c_char, c_int, c_longlong, c_ushort, c_uint, c_ulonglong, size_t}; @@ -1719,7 +1726,7 @@ pub mod llvm { Reloc: RelocMode, Level: CodeGenOptLevel, EnableSegstk: bool, - UseSoftFP: bool) -> TargetMachineRef; + FA: FloatABI) -> TargetMachineRef; pub fn LLVMRustDisposeTargetMachine(T: TargetMachineRef); pub fn LLVMRustAddAnalysisPasses(T: TargetMachineRef, PM: PassManagerRef, diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 76e24faebd93b..ec23557bf7a6e 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -68,7 +68,7 @@ LLVMRustCreateTargetMachine(const char *triple, Reloc::Model RM, CodeGenOpt::Level OptLevel, bool EnableSegmentedStacks, - bool UseSoftFloat) { + FloatABI::ABIType FA) { std::string Error; Triple Trip(Triple::normalize(triple)); const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Trip.getTriple(), @@ -81,12 +81,11 @@ LLVMRustCreateTargetMachine(const char *triple, TargetOptions Options; Options.NoFramePointerElim = true; Options.EnableSegmentedStacks = EnableSegmentedStacks; - Options.FloatABIType = - (Trip.getEnvironment() == Triple::GNUEABIHF) ? FloatABI::Hard : - FloatABI::Default; - Options.UseSoftFloat = UseSoftFloat; - if (UseSoftFloat) { - Options.FloatABIType = FloatABI::Soft; + Options.UseSoftFloat = (FA == FloatABI::Soft); + if (FA == FloatABI::Default && Trip.getEnvironment() == Triple::GNUEABIHF) { + Options.FloatABIType = FloatABI::Hard; + } else { + Options.FloatABIType = FA; } TargetMachine *TM = TheTarget->createTargetMachine(Trip.getTriple(),