Skip to content

Compiler support for embedded targets running the Thumb instruction set. #10942

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/librustc/back/arm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,

Expand Down
45 changes: 36 additions & 9 deletions src/librustc/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -146,18 +147,34 @@ 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.
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,
use_softfp
enable_segmented_stacks,
fp_abi
)
})
})
Expand Down Expand Up @@ -336,8 +353,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"); }
Expand Down Expand Up @@ -767,6 +790,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))
}
Expand Down Expand Up @@ -1019,8 +1043,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
Expand Down
10 changes: 9 additions & 1 deletion src/librustc/back/mips.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/back/rpath.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!()
Expand Down
77 changes: 77 additions & 0 deletions src/librustc/back/thumb.rs
Original file line number Diff line number Diff line change
@@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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"]
};
}
6 changes: 5 additions & 1 deletion src/librustc/back/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,

Expand Down
6 changes: 6 additions & 0 deletions src/librustc/back/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
12 changes: 9 additions & 3 deletions src/librustc/driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -82,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")
};

Expand Down Expand Up @@ -554,7 +556,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<abi::Architecture> {
for &(arch, abi) in architecture_abis.iter() {
Expand All @@ -572,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)];
Expand All @@ -592,13 +596,15 @@ 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();
let target_strs = match arch {
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 {
Expand Down
5 changes: 4 additions & 1 deletion src/librustc/driver/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -446,6 +448,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
}
}
1 change: 1 addition & 0 deletions src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
11 changes: 9 additions & 2 deletions src/librustc/lib/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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};
Expand Down Expand Up @@ -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,
Expand Down
Loading